C 17中的新:默认情况下匹配的模板模板

New in C++17: template templates that match by default

本文关键字:情况下 默认      更新时间:2023-10-16

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标准的17.3.3(3)(此处草稿)和
  • 在教派中。C 14标准的14.3.3(2或3)(此处草稿)。

对于简短,示例代码省略了详细信息。让我们扩展样本:

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<int>解析为B<int>。的确,最后一个表示B<int, int>,但是鉴于默认参数,B<int>是一种写入的明确方法。

据我所知,

原则上没有理由C 14无法理解这一点,但是对于C 14来说,推理链太复杂了。三年后,C 17理解。

顺便说一句,Clang C 编译器提供了解决此问题的-frelaxed-template-template-args选项。如果在Clang上使用模板模板,则可以断言此选项。(@rakete1111因引起叮当声的关注而得到认可。)