gpt4 book ai didi

C++ - 在模板类之外但在头文件中定义成员函数

转载 作者:行者123 更新时间:2023-12-01 14:41:37 26 4
gpt4 key购买 nike

我用一个成员函数定义了一个简单的类模板。它是在类外定义的,具有额外的(显式)特化,也在类外定义。全部在一个头文件中。如果您在多个翻译单元中包含此 header ,则会由于 One-Definition-Rule 出现链接器错误。

// Header with a template

template <class T>
class TestClass
{
public:
TestClass() {};
~TestClass() {};
bool MemberFunction();
};

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

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

到目前为止一切都很好。但是如果我将成员函数的定义放在类体中,链接器错误就会消失,并且这些函数可以在不同的翻译单元中使用。
// Header with a template

template <class T>
class TestClass
{
public:
TestClass() {};
~TestClass() {};
bool MemberFunction()
{
return true;
}
};

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

我的问题是为什么它会这样工作?我使用 MSVC 2012。ODR 在模板上有一些异常(exception),我最初认为这是原因。但是类内部/外部的“Base”函数的定义在这里有所不同。

最佳答案

14.7/5 说

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 explicitinstantiation follows a declaration of the explicit specialization.

Animplementation is not required to diagnose a violation of this rule.


第二个要点适用于您的情况。 3.2 中定义的 ODR 说明了同样的事情,尽管形式较少。
无论成员函数的非特化版本在哪里以及如何定义,特化版本定义
template <> bool TestClass<double>::MemberFunction()
{
return true;
};
必须进入 .cpp文件。如果保存在头文件中,一旦头文件被包含在一个以上的翻译单元中,就会产生 ODR 违规。 GCC 可靠地检测到这种违规行为。 MSVC 在这方面似乎不太可靠。但是,正如上面引用的那样,不需要实现来诊断违反此规则的行为。
头文件应该只包含该特化的非定义声明
template <> bool TestClass<double>::MemberFunction();
在 MSVC 中,错误的出现或消失取决于诸如函数的非专业版本的定义方式等看似无关的因素,这一事实必须是 MSVC 编译器的一个怪癖。

经过进一步研究,似乎 MSVC 实现实际上已被破坏:它的行为超出了语言规范给出的“不需要诊断”许可所允许的范围。
您在实验中观察到的行为与以下内容一致:将主函数模板声明为 inline自动使该模板显式特化 inline以及。这不应该是那样的。在 14.7.3/14 语言规范中说

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

关于C++ - 在模板类之外但在头文件中定义成员函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26305368/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com