为什么没有声明就无法从.cpp文件中获取模板功能的完全专业化? [英] Why full specialization of template function is not picked up from the .cpp file without declaration?

查看:54
本文介绍了为什么没有声明就无法从.cpp文件中获取模板功能的完全专业化?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下代码不生成编译/链接器错误/警告:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆