特化模板的多个实例化
Multiple instantiation of specialized templates
本文关键字:实例化 更新时间:2023-10-16
我有一个带有专门化的显式实例化的模板类:
// a.hh
#pragma once
template<int N>
struct A {
int foo();
};
// a.in
#include "a.hh"
template<>
int A<1>::foo() { return 1; } // specialization for N=1
template<>
int A<2>::foo() { return 2; } // specialization for N=2
// a1.cc
#include "a.in"
template struct A<1>; // explicit instantiation for N=1
// a2.cc
#include "a.in"
template struct A<2>; // explicit instantiation for N=2
以上文件用g++ 4.9.2编译成一个静态库:
g++ -Wall -c -o a1.o a1.cc
g++ -Wall -c -o a2.o a2.cc
ar rcs libtest.a a1.o a2.o
我期望a1。0包含A<1>::foo()和a2。o包含A<2>::foo(),但不包含其他方式,因为每个.cc文件中只有一个实例化。
结果是,两个目标文件都包含两个函数。VS2015RC还提供了链接器警告:
a1.obj : warning LNK4006: "public: int __thiscall A<1>::foo(void)" already defined in a2.obj; second definition ignored
a1.obj : warning LNK4006: "public: int __thiscall A<2>::foo(void)" already defined in a2.obj; second definition ignored
为什么?
同样,如果我注释掉N=2的专门化,在g++中它仍然会静默编译,即使显式实例化的N=2有一个无法解析的函数…(VS2015RC警告"没有为显式模板实例化请求提供合适的定义",如预期的那样)。
澄清 -根据标准(14.7.3.6):
如果a[…]类模板的]成员是显式特化的,那么该特化应该在第一次使用该特化之前声明,该特化会导致隐式实例化发生,在每个使用该特化的翻译单元中[.]
这段话(隐式地)指出,需要使用专门化才能实例化它。
我的问题是A<2>::foo()在a1中隐式实例化。
您的专门化不是inline
。所以你有一个翻译单位的定义包括a.in
添加inline
关键字:
template<>
inline int A<1>::foo() { return 1; } // specialization for N=1
或移动CPP文件中的定义:
// a1.cc
#include "a.hh"
template<>
int A<1>::foo() { return 1; } // specialization for N=1
template struct A<1>; // explicit instantiation for N=1
我想说你的代码
template<>
int A<1>::foo() { return 1; } // specialization for N=1
是成员函数的显式定义,因此不能执行两次。因此,确保只在一个翻译单元内。
14.7.3显式特化5显式特化类的成员不是隐式的从类模板的成员声明中实例化;相反,类模板特化的成员应该自己如果需要定义,则显式定义。
相关文章:
- 从C++实例化QML
- 设计一个只能由特定类实例化的类(如果可能的话,通过make_unique)
- 如何创建一个空的全局类并在启动时实例化它
- 在两个类中共享相同的函数调用,并在不需要时避免空实例化
- 约束和显式模板实例化
- 为什么包含windows.h会产生语法错误,从而阻止类的实例化?(C2146,C2065)
- 对象实例化调用构造函数的次数太多
- 如何使用非默认构造函数实例化模板化类
- 静态数据成员模板专用化的实例化点在哪里
- 错误的cv::face FacemarkLBF实例化
- C++的解析器在可以区分比较和模板实例化之前会做什么?
- 为什么 gcc 和 clang 为函数模板的实例化生成不同的符号名称?
- 检查某些类型是否是模板类 std::optional 的实例化
- 我有一个对象,它将在整个程序的持续时间内实例化,但一个类成员不会,我应该动态分配它吗?
- 无法使用 SWIG 在 Python 中实例化C++类(获取属性错误)
- 模板化类构造函数的模板实例化
- 在 c++ 中的模板实例化中使用带有构造函数的类作为类型参数
- 受约束的成员函数和显式模板实例化
- 对显式实例化的模板函数的未定义引用
- [temp.variadic]中关于包扩展实例化的措辞