【问题标题】:Possible forms of template template argument in the template instantiation模板实例化中模板模板参数的可能形式
【发布时间】:2012-06-16 02:04:11
【问题描述】:

模板参数的一种可能形式是类模板。 C++ 标准 (C++2003) 声明模板实例化期间模板模板参数的参数是“id 表达式”。这个非终端相当宽。它允许析构函数、重载运算符等。例如,以下代码应该可以正常编译:

template <template <typename x> class T>
struct MyClass
{
    T<int> a;
    T<double> b;
};

template <typename x> struct Helper
{
    ~Helper() { }
    x operator+(x p) { return(x[1]+p); }
    x[4] c;
};

 MyClass<Helper> p1;
 MyClass<~Helper> p2;
 MyClass<Helper::operaror+> p3;

最后两行没有任何意义。但从语法的角度来看,它们很好。语法没有(也不应该)准确地描述语言,但是第 14.3.3 段“模板模板参数”没有提到在这种情况下对语法规则的任何限制。

任何人都可以接受或反驳我的陈述:

  1. 模板模板参数只能是标识符,也可以是限定符。
  2. 如果第一点属实,这绝对值得在标准中提及。

【问题讨论】:

    标签: c++ template-templates


    【解决方案1】:

    14.3 [temp.arg] p1

    "template-argument有三种形式,对应template-parameter的三种形式:type、non-type和template。 template-id 中指定的每个 template-argument 都应与模板在其模板参数列表中声明的相应参数指定的类型和形式相匹配。

    自变量~Helper 的模板模板参数template&lt;typename&gt; class T 的类型不正确,它不是类模板。

    14.3.3 [temp.arg.template] p1

    模板template-parametertemplate-argument应该是类模板的名称,表示为id-expression

    ~Helper 不是类模板的名称。

    这很明显排除了你的例子。

    【讨论】:

    • 我期待看到关于非终端形式的文字。他们使用了更高级的语言:“应为类模板的名称”。这也是可以接受的。我的错。在我的 C++ 语法变体中,我在这种情况下使用更严格的非终结符。
    • @KirillKobelev,参见附件 A [gram] 第 1 段:“此 C++ 语法摘要旨在帮助理解。它不是该语言的准确陈述。特别是,此处描述的语法接受有效 C++ 构造的超集。" 您需要考虑规范性措辞以及语法规则。
    • 我在最初的帖子中提到了这一点:“语法不是(也不应该)准确地描述语言”(顺便说一句)。
    猜你喜欢
    • 2014-06-30
    • 2010-09-18
    • 1970-01-01
    • 1970-01-01
    • 2014-09-13
    • 1970-01-01
    • 2015-02-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多