Why full specialization of template function is not picked up from the .cpp file without declaration?

萝らか妹 提交于 2019-12-02 05:16:58

问题


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);
}

The output surprisingly is:

A::foo(T)
A::foo(double)

Why compiler is not able to pick up the correct A::foo(double) in case of main.cpp ?

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.

Also, is having 2 different version of the same function an Undefined Behavior ?


回答1:


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.

(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.)




回答2:


main.cpp cannot see the code inside other.cpp. Template specializations are of file scope.




回答3:


Why compiler is not able to pick up the correct A::foo(double) in case of main.cpp ?

The problem is that in a separate compilation model without a declaration available in the header the compiler wouldn't possibly know whether an specialization exists in any translation unit that will later be linked or whether it needs to instantiate the template. The decision in the language is that the absence of a declaration means that there is no manual specialization of the template, and thus the compiler needs to generate one now.

is having 2 different version of the same function an Undefined Behavior ?

Yes it is. Whether one of the specializations was automatically generated or not, the fact is that it is undefined behavior as it is a violation of the One Definition Rule (there are multiple definitions of the same symbol).



来源:https://stackoverflow.com/questions/13088751/why-full-specialization-of-template-function-is-not-picked-up-from-the-cpp-file

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!