c++templateslinkerc++17explicit-instantiation

How to export SFINAE-constrained ctor defined in cpp file for explicitly instantiated template class?


Here's my attempt:

If I try to compile the two TUs above and link them, I get the following error from the linker:

main.cpp:(.text+0x24): undefined reference to `Foo<2>::Foo<2, 0>(int)'
collect2: error: ld returned 1 exit status

Indeed, I don't see any symbols from foo.cpp, as this

nm foo.o

gives no output.


If I add another, un-constrained ctor, e.g.

// foo.hpp
// …
struct Foo {
    Foo(int, int);
// …

and

// foo.cpp
// …
template<int N>
Foo<N>::Foo(int, int) {}
// …

then I do get what I expect:

nm foo.o | c++filt
0000000000000000 W Foo<2>::Foo(int, int)
0000000000000000 W Foo<2>::Foo(int, int)
0000000000000000 n Foo<2>::Foo(int, int)

Solution

  • Explicitly instantiate template class doesn't instantiate template member function.

    You need to explicitly instantiate those methods too:

    // template Foo<2>::Foo<2, 0>(int); // Not supported by clang
    template Foo<2>::Foo(int);
    

    Demo Demo