У меня есть вопрос, касающийся того, как типы обнаруживаются ADL в общих ситуациях.
В частности, у меня есть некоторый «универсальный» код, где мне нужно проверять во время компиляции наличие функции, которая должна быть найдена ADL. Например:
#include "MyClass.h"struct MyClass
{
friend inline void DoSomething(MyClass& first, MyClass& second){}
}
MyClass a, b;
DoSomething(a,b); //DoSomething in MyClass will be found by ADL
У меня есть класс черты, который использует трюк sizeof, чтобы проверить наличие этой функции ADL:
//HasDoSomething.h
//type trait to check whether a type has a DoSomething function defined
template<typename T>
struct has_doSomething
{
typedef char yes;
typedef char (&no)[2];
//SFINAE eliminates this when the type is invalid
template <typename U, U>
struct Check;
template <typename U>
static yes Tester(Check<void(*)(U&, U&), &DoSomething>*);
//overload resolution prefers anything at all over ...
template <typename U> static no Tester(...);
static bool const value = sizeof(Tester<T>(0)) == sizeof(yes);
};
Класс черты / размер трюка сам по себе не важен (вы можете найти подробности в книге C ++ Template Metaprogramming, из которой я поднял ее, если вам интересно). Скорее проблема в том, что эта черта типа не будет компилироваться, если я не #include его после #include (произвольного) типа, для которого определено DoSomething, например,
#include "MyClass.h"#include "HasDoSomething.h"
или, альтернативно, я создаю фиктивный класс с объявлением функции DoSomething:
struct DummyClass
{
public:
friend inline void DoSomething(DummyClass&, DummyClass&);
private:
DummyClass(){}
};
и включите это (напрямую или через Dummy.h) в HasDoSomething.h.
Не кажется идеальным запускать ADL-поиск подобным образом, задавая порядок #include или вставляя избыточный код, так что я что-то неправильно понимаю или что-то делаю неправильно?
ADL используется только для определения набора перегрузки вызова функции.
Прежде чем компилятор сможет это сделать, он должен сначала определить, является ли это вызовом функции, выполнив обычный поиск по имени и найдя функцию.
Других решений пока нет …