c++argument-dependent-lookupc++-modules

How to make ADL work with overloaded functions across C++ modules?


I have a module A exporting a class template, that uses an overloaded function foo() dependent on the template's type argument:

module;
export module A;

export void foo(bool a) {}
export void foo(int a) {}

export template <class T>
struct call {
    void (*fn)(T) = foo;
};

Then in mobule B I import module A and try to use the class with a custom type and a custom overloaded function foo() for that type:

module;
export module B;
import A;

void foo(float a) {}

call<float> c = {};

But clang fails with an error:

error: address of overloaded function 'foo' does not match required type 'void (float)'

Do I understand correctly that modules resolve ADL only by what that module actually sees, e.g. module A can only see what it defines itself and what it imports?

Is it somehow possible to make module A see new overloads and make this work automatically without explicitly assigning the function?


Solution

  • There's no ADL involved.

    1. ADL only takes place in function call expressions.

    2. ADL finds nothing for fundamental types.

    The code doesn't work even if you write everything in a single TU:

    void foo(bool a) {}
    void foo(int a) {}
    
    template <class T>
    struct call {
        void (*fn)(T) = foo;
    };
    
    void foo(float a) {}
    
    call<float> c = {};