【问题标题】:Partialy specialization with function pattern parameters具有函数模式参数的部分特化
【发布时间】:2017-01-15 23:32:55
【问题描述】:

下面的代码有问题:

template<typename Name>
class Person;

template<typename Name, typename FamilyNmae>
class Person {};

template<typename Name, typename FamilyName>
class Person < Name(FamilyName) >
{
public:
   Person(Name a)
      : k{ a }
   {

   }

private:
   Name k;
   FamilyName l;
};

这段代码无法编译(C2977 'Person': too many template arguments),但如果我接下来编译:

template<typename Name>
class Person;

//template<typename Name, typename FamilyNmae>
//class Person {};

template<typename Name, typename FamilyName>
class Person < Name(FamilyName) >
{
public:
   Person(Name a)
      : k{ a }
   {

   }

private:
   Name k;
   FamilyName l;
};

它可以正确编译。但我找不到收到错误的规则。 我的意思不是编译器作者的解释,而是标准的解释。 有人知道吗?

【问题讨论】:

  • class Person &lt; Name(FamilyName) &gt; 对您意味着什么?
  • 这只是检查类型如何放入模板实例化的模式:Person<:string> person(std::string("Denis"));
  • 不是标准,但很有趣:stackoverflow.com/questions/11968994/…
  • 我认为这两条注释行不是专业化的,它们不专业化任何东西。因此它们被视为类 Person 的重新声明。类不能重载,只有函数可以。
  • @Ripi2 谢谢你是对的

标签: c++ templates generics


【解决方案1】:

在最新的publicly available draft 中,见 14.0.0.5(如下所示)和 14.5.5。

类模板不得与任何其他模板同名, 类、函数、变量、枚举、枚举器、命名空间或类型 在相同的范围 (3.3) 中,但在 (14.5.5) 中指定的除外。

关于你到底要问什么并不那么明确,但“除外”子句是关键部分。这意味着无法完成“重载”类模板。

如果你按照14.5.5的参考,可以看到你想做的,只能通过模板特化来完成。

使用 14.5.5.3 作为如何正确专门化类模板的指南,您可以执行以下操作:

class EmptyName {}; //just a placeholder

template<typename Name, typename FamilyName>
class Person {};

template<typename Name>
class Person<Name, EmptyName> {};

请注意,带有 2 个参数的模板声明如何首先定义为“主模板”,然后您将专门研究它。

【讨论】:

  • 谢谢你的回答我知道它只是由于超载而发生的。编译器尝试将参数应用于新的特化,但特化没有收到任何参数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-10
  • 1970-01-01
相关资源
最近更新 更多