ここでは一例です:私はこのプログラムをコンパイルしようとしたとき引数依存の検索および関数テンプレート
#include <string>
#include <algorithm>
#include <memory>
using std::string;
int main()
{
string str = "This is a string";
// ok: needn't using declaration, ADL works
auto it = find(str.begin(), str.end(), 'i');
// error: why ADL doesn't work?
std::shared_ptr<string> sp = make_shared<string>(str);
}
は、コンパイラが訴え:
error: no template named 'make_shared'; did you mean 'std::make_shared'?
std::shared_ptr<string> sp = make_shared<string>(str); // error...
^~~~~~~~~~~
std::make_shared
私は最初の関数find
にはないと思います引数に依存する検索(ADL
)のため、using
宣言が必要です。コンパイラは、string
が存在するネームスペース(つまり、std
)を検索し、find
。しかし、2番目の関数make_shared
では、ADL
が機能しないようです。代わりにstd::make_shared
またはusing
宣言を使用する必要があります。私は2つの関数テンプレートの定義が異なっている知っている:前者は関数のパラメータ型としてそのテンプレート偶然にの1(typename T
またはそのような何かを)取り、同じ型を返します。後者は、関数パラメータパックを関数パラメータとして取り込み、その戻り値の型は別のテンプレートパラメータです。この違いはADL
を無効にしますか?あるいは、その質問に答えるのを手伝って、参考文献を提供することができますか?
最初の使用法は脆弱です。イテレータの型が 'std'に存在するという不特定の状況に頼っています。別の日にイテレータの型が 'const char *'ならば、それはコンパイルされません。 –
私はそれが 'using'宣言を省略することは脆い方法であることを知っています。 2番目のものと比較して> _ <||| – chihyang
@chihyang:良い例は 'begin(str)'でしょう。 – Jarod42