【问题标题】:Why is explicit specialization of a member not allowed without specializing the class?为什么在不专门化类的情况下不允许显式专门化成员?
【发布时间】:2016-10-13 18:52:18
【问题描述】:

C++ 标准规定如下:

在类模板或成员模板的成员的显式特化声明中 出现在命名空间范围内,成员模板和它的一些封闭类模板可能会保留 非特化,除了声明不应显式特化类成员模板,如果它 封闭类模板也没有明确专门化。 (自 C++11 起为 14.7.3/16,旧标准为 14.7.3/18)

这意味着以下是不可能的:

template<typename T>
class foo {
  template<typename U>
  void bar();
};

template<typename T>
template<>
void foo<T>::bar<some_type>(){
}

已经有多个与此相关的问题的人的问题,或多或少地通过“标准如此说”来回答。我不太明白为什么会存在这种限制。

【问题讨论】:

  • 粗略猜测:如果存在T=intU unspecialized 的特化,以及U=intT unspecialized 的特化,如果T=int 应该取哪一个和U=int?
  • 哦,现在我觉得自己很蠢……
  • 我应该回答这个问题还是你想回答?
  • 想象一下你将如何在foo 的专业化中解决它,它根本没有方法bar...

标签: c++ templates standards language-lawyer explicit-specialization


【解决方案1】:

感谢 JohnB 的回答:

如果只有一个类(例如T=int)有一个专门化,而另一个专门化只针对成员(例如U=int),则无法决定使用哪个专门化。

skyjpack 的另一点:

可能有一个没有成员函数的类特化。

【讨论】:

    【解决方案2】:

    模板函数在第一次使用或专门化时被实例化。

    当你进行部分特化时,你不能实例化函数,因为它仍然是模板函数。因此,当您进行特化时,编译器必须以某种方式理解您已经进行了部分实例化并将其与您的实例化相匹配,这可能会导致困难。

    人们在 cmets 中说,这可能会导致歧义,但很多事情都会导致歧义。例如,考虑重载函数。如果调用哪个重载函数不明确,编译器会告诉你。在这种情况下也是如此。

    【讨论】:

    • 我见过类似的问题(“为什么模板参数推导不适用于构造函数”),其中某些内容是不允许的,因为它是模棱两可的。我真的只是想知道,什么样的情况会导致歧义。
    • 另外,我问的是显式(完全)专业化,而不是部分专业化,但我明白你的意思。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多