Поиск, зависящий от аргумента — когда это делается, что ищется и как вы можете принудительно (или предотвратить) это?

У меня возникают проблемы с пониманием правил поиска по аргументу (Кенига).

Рассмотрим код ниже:

#include <iostream>

using namespace std;

namespace adl
{
struct Test { };
void foo1(Test const &) { cout << "ADL used (foo1)" << endl; }
void foo2(Test const &) { cout << "ADL used (foo2)" << endl; }
void foo3(Test const &) { cout << "ADL used (foo3)" << endl; }
}

struct foo1
{
foo1() { }

template<class T>
foo1(T const &) { cout << "ADL not used (foo1)" << endl; }

template<class T>
void operator()(T const &) const { cout << "ADL not used (foo3)" << endl; }
};

template<class T> void foo2(T const &)
{ cout << "ADL not used (foo2)" << endl; }

int main()
{
adl::Test t;
foo1 foo3;
(foo1(t));
(foo2(t));
(foo3(t));
}

Его вывод:

ADL не используется (foo1)
ADL используется (foo2)
ADL не используется (foo3)

Я ожидал, что все они будут использовать ADL, но я был удивлен, что только некоторые из них сделали.

Какие (потенциально кровавые, я знаю) подробности за правилами ADL?
Я достаточно хорошо понимаю концепцию, но у меня проблемы с деталями.

Какие области поиска обыскиваются, когда они обыскиваются и когда они не обыскиваются?

Можно ли вообще сказать, используется ли ADL, не просматривая все #includeфайлы перед заданной строкой кода? Я ожидал, что функторы и функции будут вести себя одинаково с точки зрения [не] маскирования ADL, но, очевидно, они этого не делают.

Есть ли способ сила ADL в тех случаях, когда это не делается автоматически (например, как указано выше), и вы не знаете пространства имен класса (например, в шаблоне)?

6

Решение

Ваша проблема на самом деле не с аргументно-зависимым поиском. Прежде всего, зависимый от аргумента поиск, возможно, появляется только при выполнении неквалифицированного поиска функций. При звонке foo1(t) foo1 является типом и его шаблонный конструктор называется. Так же, foo3(t) это квалифицированный поиск, потому что foo3 является объектом, и оператор вызова функции ищется в классе объекта foo1, Единственное место, где поиск аргументов входит в картину, это вызов foo2(t) где поиск находит кандидатов:

  1. ::foo2<adl::Test>(adl::Test const&)
  2. ::adl::foo2(adl::Test const&)

Эти две функции передаются для разрешения перегрузки, и, поскольку обе функции одинаково хороши, они соответствуют не шаблонной функции.

Ваш вопрос на самом деле три вопроса:

  1. Кровавые детали поиска имени слишком широки, и, таким образом, этот вопрос является просьбой написать эссе, которое я игнорирую.
  2. Ваш второй вопрос расширяется до еще трех вопросов, только один кажется актуальным:
    1. Какие области поиска? При поиске неквалифицированного имени функции в определении функции правила зависят от того, является ли какое-либо из имен зависимым именем. Если такого имени нет (т. Е. В не шаблонном коде или в шаблонном коде, где имена могут быть определены на первом этапе), выполняется поиск имени, включающего в себя пространства имен и пространства имен, связанные с его аргументом. В противном случае имя ищется только в связанных пространствах имен.
  3. Можно ли принудительно вызвать зависимый поиск? Это всегда делается для неквалифицированных поисков функций, если есть хотя бы один аргумент, но имена, найденные в противном случае, могут лучше подходить. Конечно, вам нужно вызывать неквалифицированную функцию, иначе это не будет сделано.
5

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]