如何导出cpp文件中定义的SFINAE约束的ctor以用于显式实例化的模板类?

问题描述 投票:0回答:1

这是我的尝试:

  • 定义
    Foo
    模板类的标头,并仅针对 NTTP
    N
    的给定值声明但不定义 ctor,
    // foo.hpp
    #include <type_traits>
    
    template<int N>
    struct Foo {
        template<int M = N, std::enable_if_t<M == 2, int> = 0>
        Foo(int);
    };
    
  • 定义该 ctor 的 cpp 文件并显式实例化
    Foo
    以获得对应于未 SFINAEd 的 ctor 的值,
    // foo.cpp
    #include "foo.hpp"
    
    template<int N>
    template<int M, std::enable_if_t<M == 2, int>>
    Foo<N>::Foo(int) {}
    
    template struct Foo<2>;
    
  • 主要 TU,实例化
    Foo<2>
    类的对象,
    // main.hpp
    #include "foo.hpp"
    
    int main() {
        Foo<2>{0};
    }
    

如果我尝试编译上面的两个 TU 并链接它们,我会从链接器中收到以下错误:

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

确实,我没有看到任何来自

foo.cpp
的符号,因为这个

nm foo.o

没有输出。


如果我添加另一个不受约束的 ctor,例如

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

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

然后我确实得到了我所期望的:

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)
c++ templates linker c++17 explicit-instantiation
1个回答
0
投票

显式实例化模板类不会实例化模板成员函数。

您也需要显式实例化这些方法:

template Foo<2>::Foo<2, 0>(int);

演示

© www.soinside.com 2019 - 2024. All rights reserved.