C++ - Define member function outside template-class but in header

。_饼干妹妹 提交于 2019-12-01 11:56:02

14.7/5 says

5 For a given template and a given set of template-arguments,

  • an explicit instantiation definition shall appear at most once in a program,
  • an explicit specialization shall be defined at most once in a program (according to 3.2), and
  • both an explicit instantiation and a declaration of an explicit specialization shall not appear in a program unless the explicit instantiation follows a declaration of the explicit specialization.

An implementation is not required to diagnose a violation of this rule.

The second bullet applies to your case. The ODR defined in 3.2 says the same thing, albeit in a less distilled form.

Regardless of where and how the non-specialized version of member function is defined, the specialized version definition

template <> bool TestClass<double>::MemberFunction()
{
    return true;
};

has to go into a .cpp file. If kept in the header file, it will produce an ODR violation once the header gets included into more than one translation unit. GCC reliably detect this violation. MSVC seems to be less reliable in that regard. But, as the quote above states, an implementation is not required to diagnose a violation of this rule.

The header file should only contain a non-defining declaration of that specialization

template <> bool TestClass<double>::MemberFunction();

The fact that in MSVC the error appears or disappears depending on such seemingly unrelated factor as how the non-specialized version of the function is defined must be a quirk of MSVC compiler.


After further research, it appears that MSVC implementation is actually broken: its behavior goes beyond what's allowed by the "no diagnostic is required" permission given by the language specification.

The behavior you observed in your experiments in consistent with the following: declaring the primary function template as inline automatically makes the explicit specialization of that template inline as well. This is not supposed to be that way. In 14.7.3/14 the language specification says

An explicit specialization of a function template is inline only if it is declared with the inline specifier or defined as deleted, and independently of whether its function template is inline.

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