Вызов функции по ADL из другой функции

У меня есть вопрос, касающийся того, как типы обнаруживаются 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 или вставляя избыточный код, так что я что-то неправильно понимаю или что-то делаю неправильно?

1 ответ

Решение

ADL используется только для определения набора перегрузки вызова функции.
Прежде чем компилятор сможет это сделать, он должен сначала определить, является ли это вызовом функции, выполнив обычный поиск по имени и найдя функцию.

Другие вопросы по тегам