简体   繁体   中英

How to make an overloaded function a dependent name, so two-phase lookup finds it?

Look at this example:

template <typename TYPE>
struct Foo {
    static constexpr auto a = bar(TYPE());
    static constexpr auto b = static_cast<int (*)(TYPE)>(bar);
};

struct Bar {};

constexpr int bar(Bar) {
    return 42;
}

int main() {
    auto a = Foo<Bar>::a;
    auto b = Foo<Bar>::b;
}

At the definition of Foo , bar is unknown to the compiler. But it's a not a problem at the initialization of Foo::a , because bar(TYPE()) is a dependent expression, so ADL lookup will find bar later at the second phase of lookup. But it's a problem at the initialization of Foo::b , because bar is not a dependent expression, so the compiler complains that bar is undeclared ( godbolt ). So I can call bar ( Foo::a ), but I cannot take its address ( Foo::b ).

Is there any trick so can I get the address of bar (besides the obvious solution that I move Foo after bar )? For example, somehow make an expression which is dependent on TYPE and returns bar 's address?

You can't , unfortunately: even if bar were somehow dependent, ADL would never be performed for it since it isn't a function being called . (Put differently, unqualified names that aren't the function name in a dependent call are always looked up in the template definition.) The closest you can do is to use (and specialize!) a trait and write bar_trait<TYPE>::bar or make your own wrapper function for bar and take the address of that (which might or might not be good enough).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM