c++ - 模板模板参数在 Clang 但不是 GCC 下导致编译器错误

标签 c++ templates language-lawyer

<分区>

同时帮助解决 too many template parameters in template template argument 中提到的问题我脑子里出现了一个问题:在这种情况下,哪个编译器是正确的编译:

template <template <typename, typename> class Op>
class Function
{
};

template <typename A, typename B, bool is_f = std::is_floating_point<A>::value || std::is_floating_point<B>::value > struct Operator;

template <typename A, typename B>
struct Operator<A, B, false>
{};


template <typename A, typename B>
struct Operator<A, B, true>
{};

using FunctionOperator = Function<Operator>;


int main(int argc, char * argv[]){
    std::cout << "hi!\n";
    return 0;
}

GCC 7+ 编译它没有错误。 Clang 6 及更高版本给出错误,表明作为模板参数传递的 Operator 模板存在问题:

tmp.cpp:19:35: error: template argument has different template parameters than its corresponding template parameter
using FunctionOperator = Function<Operator>;
                                  ^
tmp.cpp:8:1: note: too many template parameters in template template argument
template <typename A, typename B, bool is_f = std::is_floating_point<A>::value || std::is_floating_point<B>::value > struct Operator;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
tmp.cpp:3:11: note: previous template template parameter is here
template <template <typename, typename> class Op>
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.

显然,即使提供了默认的第三个参数,它也将其视为三参数模板。那么问题来了,哪个编译器是正确的?标准对这种情况有说明吗?

PS 我不需要解决此类问题的方法,因为它非常简单。我只想知道“谁对谁错”

最佳答案

Gcc 是正确的。 Clang 似乎不符合 C++17。

自 C++17 ( CWG 150 ) 起,template template argument 允许默认模板参数匹配模板参数较少的模板模板参数。

template<class T> class A { /* ... */ };
template<class T, class U = T> class B { /* ... */ };
template <class ...Types> class C { /* ... */ };

template<template<class> class P> class X { /* ... */ };
X<A> xa; // OK
X<B> xb; // OK in C++17 after CWG 150
         // Error earlier: not an exact match
X<C> xc; // OK in C++17 after CWG 150
         // Error earlier: not an exact match

Operator 有 3 个模板参数,第 3 个有默认值,那么它可以作为模板模板参数 Op 的参数,即使它只需要两个模板参数。

关于c++ - 模板模板参数在 Clang 但不是 GCC 下导致编译器错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51284346/

相关文章:

c++ - C++ 中的类型映射

c++ - 带有参数包的类模板的构造函数给出 C3520 错误

c - 在 GCC 上设置 packed long long 的正确对齐以与 avx2 指令一起使用

c++ - move std::vector 时是否需要保留容量?

c++ - 如何编译非类型模板参数?

c++ - 我应该在 operator= 中使用 pass-by-const-reference 吗?

c++ - 没有匹配的成员函数来调用 'push_back'错误

C++ 变量类型条件

java - 比较 Java 中的泛型

c++: string::find 对于空输入字符串的行为是否定义明确