使用g++编译时静态函数的模板专用化
Template specialization for static function when compiling with g++
为什么以下代码在使用编译时不起作用
$g++temp_main.cpp temp_spec.cpp/tmp/ccirjc3Y.o:temp_spec.cpp:(.text+0x100):"my::say()"的多重定义/tmp/ccSo7IVO.o:temp_main.cpp:(.text$_ZN2myLi0EE3sayEv[my::say()]+0x0):这里首先定义的collect2:ld返回了1个退出状态
我试图只在使用时对静态函数进行专门化参数0。
temp_gen.h:
#ifndef temp_gen_h
#define temp_gen_h
#include <iostream>
template<int N>
struct my
{
static void say();
};
template<int N>
void my<N>::say()
{
std::cout << "generic " << N << std::endl;
}
#endif
temp_spec.h:
#ifndef temp_spec_h
#define temp_spec_h
#include <iostream>
#include "temp_gen.h"
template<>
void my<0>::say()
{
std::cout << "specialized " << 0 << std::endl;
}
#endif
temp_spec.cpp:
#include "temp_spec.h"
temp_main.cpp:
#include "temp_gen.h"
int main(int argc, char* argv[])
{
my<0>::say(); //should say "specialized 0"
my<1>::say(); //should say "generic 0"
}
在main.cpp
中,您没有专门化模板类,这是因为您没有包括temp_spec.h
。
正如Vaughn-Cato所指出的(见注释),您应该将专用方法(不再是模板方法)的定义移动到temp_spec.cpp
。
我认为(但我不是这方面的专家)您应该始终将specialization直接放在通用模板的下方(在同一个头文件中),因为无论何时包含此内容,您都希望定义专门的模板,否则当发生此类错误时,您会感到困惑。但是,您可以只在temp_gen.h
的底部包含temp_spec.h
。
我相信,由于模板专用化的实现在标头中,您需要将其标记为inline
,以便编译器/链接器知道您可以违反一个定义规则。
使用n3337版本的标准(强调矿):
14.7.3显式专业化[temp.exp.spec]
6/如果模板、成员模板或类模板的成员是显式专门化的,则应在首次使用该专门化之前声明该专门化,这将导致隐式实例化,在发生此类使用的每个翻译单元中;不需要进行诊断。
因为在main
中,my<0>::say
的专业化是不可见的,所以会发生隐式实例化,最终会出现上述情况:不需要诊断(来自编译器)。
请注意,只有在声明了泛型对应项之后,才能声明专门化。
相关文章:
- 给定一个C++嵌套的私有结构类型,是否有从文件范围静态函数访问它的策略
- 检查编译时是否存在静态函数
- 名称隐藏对静态函数继承的实例使用
- 如果 C 函数仍然可以间接执行(通过回调函数),那么将它声明为静态函数是否是一种不好的做法?
- 类中静态函数C++意外结果
- 在工人类中使用不同类的静态函数进行实验
- 类 Referention 中C++回调函数引用非静态函数
- 指向模板上下文中的成员函数或静态函数的指针
- 如何检测 Clang AST C++中的静态函数
- 内联asm编译器屏障(内存阻塞器)是算作外部函数,还是算作静态函数调用
- 如何在静态函数中使用成员函数数组
- (2 问题)"类"类型重新定义(即使 #pragma 一次),以及静态函数内的静态成员对象初始化?
- 生成代码(在编译时)以调用模板的每个实例化的静态函数
- C++无法访问或使用静态函数
- 如何将 cpp 文件中的静态函数公开给其他文件
- 模板专用化与静态函数模板
- 使用g++编译时静态函数的模板专用化
- C++模板,静态函数专用化
- 继承的静态函数能否访问重写的静态专用数据成员
- 专用嵌套类的静态函数会导致编译器错误 C3855 (MSVC9)