【问题标题】:Out of class definition of member function template in the presence of a member function of the same name - compiler divergence在存在同名成员函数的情况下,成员函数模板的类定义 - 编译器分歧
【发布时间】:2019-05-29 13:44:06
【问题描述】:

考虑这个包含成员函数和成员函数模板的类模板示例,两者都命名为f,然后尝试定义和专门化成员函数模板:

template<typename T>
struct A {
    void f();
    template<typename U>
    void f();
};

template<>
template<typename U>
void A<double>::f() { }

template<>
template<>
void A<double>::f<int>() { }

这合法吗?成员函数模板定义应该怎么写?

f的第一个定义中,模板声明是否确保应该选择成员函数模板f而不是成员函数f,即使模板参数没有出现在类型中?我认为没有任何方法可以进一步消除歧义,因为写 ::template f()::f&lt;U&gt;()::f&lt;&gt;() 或它们的组合似乎无济于事。

编译结果:

  • clang:在f&lt;int&gt; 的特化处出现堆栈跟踪崩溃
  • Visual Studio:编译成功
  • gcc:在 f 的第一个定义处编译错误(关于正在定义的 f 的歧义)
  • EDG:编译成功

相比之下,每个编译器都接受命名空间范围内的等价物:

namespace X {
    void f();
    template<typename T>
    void f();
}
template<typename T>
void X::f() { }
template<>
void X::f<int>() { }

【问题讨论】:

    标签: c++ templates overloading language-lawyer ambiguous


    【解决方案1】:

    这是一份语言缺陷报告DR 1665,目前处于草稿状态。

    正如标准所说的那样

    具有给定名称和类型的普通(非模板)成员函数和可用于生成相同类型的特化的同名成员函数模板都可以在类中声明。当两者都存在时,除非提供显式模板参数列表,否则使用该名称和类型指的是非模板成员。

    还有一个开放的 GCC 错误报告,其中的示例与您的非常相似:https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64063

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-04-11
      • 1970-01-01
      • 1970-01-01
      • 2020-08-12
      • 1970-01-01
      • 1970-01-01
      • 2017-08-04
      • 1970-01-01
      相关资源
      最近更新 更多