首先,我有一个类的头文件,一个没有定义的专门化声明(来自互联网的代码示例)
$ cat foo.h
template<typename T>
class foo{
public:
static void init(){
return;
}
};
template<> void foo<int>::init();
然后有2个用于模板专业化的实现文件
$ cat foo_int.cpp
#include "foo.h"
#include<stdio.h>
template<>
void foo<int>::init(){
printf("init int foo\n");
}
$ cat foo_float.cpp
#include "foo.h"
#include<stdio.h>
template<>
void foo<float>::init(){
printf("init float foo\n");
}
最后我得到了一个主文件
$ cat main.cpp
#include "foo.h"
int main(){
foo<int>::init();
foo<float>::init();
}
如果我在没有优化的情况下编译它并运行它,它会给出:
g ++ foo_int.cpp foo_float.cpp main.cpp&amp;&amp; a.out的
init int foo
init float foo
如果我添加优化,那么结果就不同了:
$ g ++ foo_int.cpp foo_float.cpp main.cpp -O2&amp;&amp; a.out的
init int foo
结果不同。来自互联网的一些解释说,这是由于“弱符号”的一些内部机制所致。在gcc实现中,但我的问题是:
是&#34;弱符号&#34; /&#34;强符号&#34; gcc / g ++的概念,或者它是c / c ++语言规范的一部分。
- 醇>
如果调试和发布结果不同,我应该说这是gcc / g ++的错误/问题,关于&#34;弱符号&#34;机制?作为开发人员,我不希望我的调试版本与发布版本的行为不同。
我试过铿锵,不幸的是同样的错误。这是一个&#34;可接受的&#34;调试/发布的C / C ++案例&#34;应该&#34;表现得如此不同?
答案 0 :(得分:3)
您违反了一个定义规则 - 您的程序包含两个 foo<float>::init
的定义。
编译单元foo_float.cpp
中出现一个定义,另一个定义出现在编译单元main.cpp
中。
违反一个定义规则意味着未定义的行为 - 在这种情况下,可能发生的是:
foo_float.cpp
的函数版本放在可执行文件中。main.cpp
时编译器内联函数 - 当然,它会内联main.cpp
函数的版本。答案 1 :(得分:3)
语言定义要求在使用之前声明显式特化:
如果是模板,成员模板或类模板的成员 明确专业化然后宣布专业化 在第一次使用该特化之前会导致一个 隐式实例化发生在每个翻译单元中 发生了这种用途;无需诊断。 [temp.expl.spec] / 6。
foo<float>::init()
从main
调用foo_float.cpp
时没有声明显式特化,但{{1}}中有明确的特化,所以程序的行为未定义。