【问题标题】:New in C++17: template templates that match by defaultC++17 中的新功能:默认匹配的模板模板
【发布时间】:2019-03-03 00:12:26
【问题描述】:

C++17 标准说可以做到这一点:

template<class T, class U = T> class B { /* ... */ };
template<template<class> class P> class X { /* ... */ };

X<B> xb; // OK in C++17; ill formed in C++14

C++14 标准使相同的代码成为错误。

旧的 C++14 规则对我来说很有意义。新的 C++17 规则没有。发生了什么变化?

上面的示例代码供参考

  • 在第。 C++17 标准(草案here)的 17.3.3(3) 和
  • 在第。 C++14 标准的 14.3.3(2 或 3)(草案here)。

【问题讨论】:

  • 一些编辑请在 [c++14] 和 [c++17] 问题中添加 [c++] 标签。但是,这个问题可能太小而无法引起一般 [c++] 观察者的兴趣。只有专门观看 [c++14] 和/或 [c++17] 的观察者才需要注意。
  • 阅读标签维基,你总是标签c++以及版本化的。
  • @PasserBy 当然。没关系。

标签: c++ templates c++14 language-lawyer c++17


【解决方案1】:

为简洁起见,示例代码省略了详细信息。让我们扩展示例:

template<class T, class U = T> class B { /* ... */ };
template<template<class> class P> class X {
    P<int, int> pii; // error: P has been declared to take only one argument
    P<int>      pi;  // OK
    P<char>     pc;  // OK
    /* ... */
};

X<B> xb; // OK in C++17; ill formed in C++14

最后一行将P&lt;int&gt; 解析为B&lt;int&gt;。确实,最后一个意思是B&lt;int, int&gt;,但鉴于默认参数,B&lt;int&gt; 是一种明确的写法。

原则上,据我所知,C++14 没有理由不理解这一点,但推理链对于 C++14 来说太复杂了。三年后,C++17 明白了。

顺便说一句,Clang C++ 编译器提供了一个-frelaxed-template-template-args 选项来解决这个问题。如果在 Clang 上使用模板模板,您可能会断言此选项。 (@Rakete1111 因引起 Clang 选项的注意而受到认可。)

【讨论】:

  • 我的困惑似乎是语言障碍引起的,我错误地解释了答案的第二段,我刚刚理解了。删除了我原来的评论。
  • @Fureeish 你是对的。第二段简洁、简短、浓缩。第二段可以写得更长,但这个话题太混乱了,我不确定更长的时间会有所帮助。幸运的是,代码可能比段落解释得更好。
  • 还可能需要提及 -frelaxed-template-template-args 以便 clang 接受这一点。
  • 我很乐意接受别人的更好答案,而不是我自己的;但既然我自己的仍然是唯一的,我现在就接受它。
猜你喜欢
  • 2018-10-12
  • 1970-01-01
  • 2019-01-24
  • 2011-08-07
  • 1970-01-01
  • 1970-01-01
  • 2011-07-15
  • 1970-01-01
  • 2018-07-15
相关资源
最近更新 更多