为什么没有声明就无法从.cpp文件中获取模板功能的完全专业化? [英] Why full specialization of template function is not picked up from the .cpp file without declaration?
问题描述
以下代码不生成编译/链接器错误/警告:
Following code generate no compilation/linker error/warning:
// A.h
#include<iostream>
struct A
{
template<typename T>
static void foo (T t)
{
std::cout << "A::foo(T)\n";
}
};
void other ();
// main.cpp
#include"A.h"
int main ()
{
A::foo(4.7);
other();
}
// other.cpp
#include"A.h"
template<>
void A::foo (double d)
{
cout << "A::foo(double)\n";
}
int other ()
{
A::foo(4.7);
}
令人惊讶的输出是:
A::foo(T)
A::foo(double)
为什么在main.cpp
的情况下编译器无法选择正确的A::foo(double)
?
Why compiler is not able to pick up the correct A::foo(double)
in case of main.cpp
?
同意,如果A.h
中有如下所示的声明,则不会出现预期的问题:
Agree that, there is no issue as expected, if there is a declaration in A.h
like below:
template<> void A::foo (double);
但这不是问题,因为在链接时,编译器具有专用版本.
But that's not the concern, because at link time, compiler has the specialized version.
此外,同一功能有2个不同版本是未定义行为吗?
Also, is having 2 different version of the same function an Undefined Behavior ?
推荐答案
在模板实例化时,所有显式的特殊化声明必须 visible .由于A::foo<double>
的显式专业化声明在一个翻译单元中可见,而在另一翻译单元中不可见,因此该程序格式错误.
All explicit specialization declarations must be visible at the time of the template instantiation. Since your explicit specialization declaration for A::foo<double>
is visible in one translation unit but not the other, the program is ill-formed.
(实际上,编译器将实例化main.cpp
中的主模板,并实例化other.cpp
中的显式专用模板.无论如何,这仍然会违反ODR.)
(In practice, the compiler will instantiate the primary template in main.cpp
and the explicitly-specialized one in other.cpp
. That would still an ODR violation anyway.)
这篇关于为什么没有声明就无法从.cpp文件中获取模板功能的完全专业化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!