class 模板与默认参数作为模板模板 class 更小参数的不一致处理
inconsistent treatment of class template with defaulted argument as template template class argument of smaller arity
以下代码段在 C++17 上被 Clang 拒绝,在 C++17 上被 GCC 接受,在 C++14 上被 GCC 拒绝。这与所有最新的编译器版本一致。什么是正确的行为?
template <class T, class = int>
struct test1 {};
template <class T, template <class> class>
struct test2 {};
using test_t = test2<int, test1>;
编辑:显然这实际上是在 Clang 上实现的,它只需要一个显式标志:-frelaxed-template-template-args
使用 -pedantic
.
时不包括在内
GCC 的 是 正确的行为。它与被 C++17 接受的 p0522r0 一致。
来自论文的介绍:
Template template-parameters only bind to arguments with matching
parameter lists. Matching is currently defined as an exact match; each
template parameter in the argument's parameter list must have the same
kind and type as the corresponding parameter in the
template-parameter's parameter list. (There is an ill-advised
exception to this rule when a parameter pack appears in the
template-parameter's parameter list; this paper preserves that special
behavior.) The matching rules exclude many reasonable arguments. This
paper adjusts the matching rules to invoke partial ordering to
determine when a template template-argument is a valid match for a
template-parameter.
该论文还包含将发生变化的代码示例,此代码段与您观察到其行为的示例非常相似:
template <template <typename> class> void FD();
template <typename, typename = int> struct SD { /* ... */ };
FD<SD>(); // OK; error before this paper (CWG 150)
以下代码段在 C++17 上被 Clang 拒绝,在 C++17 上被 GCC 接受,在 C++14 上被 GCC 拒绝。这与所有最新的编译器版本一致。什么是正确的行为?
template <class T, class = int>
struct test1 {};
template <class T, template <class> class>
struct test2 {};
using test_t = test2<int, test1>;
编辑:显然这实际上是在 Clang 上实现的,它只需要一个显式标志:-frelaxed-template-template-args
使用 -pedantic
.
GCC 的 是 正确的行为。它与被 C++17 接受的 p0522r0 一致。
来自论文的介绍:
Template template-parameters only bind to arguments with matching parameter lists. Matching is currently defined as an exact match; each template parameter in the argument's parameter list must have the same kind and type as the corresponding parameter in the template-parameter's parameter list. (There is an ill-advised exception to this rule when a parameter pack appears in the template-parameter's parameter list; this paper preserves that special behavior.) The matching rules exclude many reasonable arguments. This paper adjusts the matching rules to invoke partial ordering to determine when a template template-argument is a valid match for a template-parameter.
该论文还包含将发生变化的代码示例,此代码段与您观察到其行为的示例非常相似:
template <template <typename> class> void FD();
template <typename, typename = int> struct SD { /* ... */ };
FD<SD>(); // OK; error before this paper (CWG 150)