Вот пример:Аргумент-зависимый поиск и шаблоны функций
#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
не делает требуется using
декларация из-за зависимого от аргумента поиска (ADL
): компилятор будет искать пространство имен, где string
проживает (т.е. std
) для определения find
. Но для второй функции make_shared
, кажется, что ADL
не работает: вместо этого я должен использовать декларацию или using
. Я знаю, что определения двух шаблонов функций различны: первый принимает один из своих шаблонных параметров (typename T
или что-то в этом роде) как тип параметра функции и возвращает тот же тип. Последний принимает пакет параметров функции как параметр функции, а его возвращаемый тип является другим параметром шаблона. Разница в том, что отключает ADL
? Или вы могли бы ответить на вопрос и предложить некоторые рекомендации?
Первое использование - хрупкое. Вы полагаетесь на неопределенное обстоятельство, что тип итератора живет в 'std'. Если в другой день тип итератора будет 'const char *', он не будет компилироваться. –
Я знаю, что это хрупкий способ пропустить объявление 'using'. Точно так же, как сравнение со вторым> _ <|||. – chihyang
@chihyang: Лучшим примером будет 'begin (str)'. – Jarod42