如何导出显式实例化模板类中SFINAE约束的cpp构造函数?
模板类成员模板构造函数的链接错误问题
问题复现步骤
- 头文件定义带SFINAE约束的模板类
声明仅当非类型模板参数N为2时才存在的构造函数:
// foo.hpp #include <type_traits> template<int N> struct Foo { template<int M = N, std::enable_if_t<M == 2, int> = 0> Foo(int); };
- 实现文件定义构造函数并显式实例化模板
// 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>;
- 主翻译单元实例化对象
// main.cpp #include "foo.hpp" int main() { Foo<2>{0}; }
链接错误现象
编译并链接两个翻译单元时,链接器报错:
main.cpp:(.text+0x24): undefined reference to `Foo<2>::Foo<2, 0>(int)' collect2: error: ld returned 1 exit status
执行nm foo.o查看目标文件符号表,无任何输出,说明受SFINAE约束的构造函数符号未被生成。
对比测试:添加无约束构造函数
若在头文件中新增一个无约束的构造函数:
// 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)
内容的提问来源于stack exchange,提问作者Enlico
相关产品推荐
相关产品推荐

