【问题标题】:Template template argument causes compiler error under Clang but not GCC [duplicate]模板模板参数导致 Clang 下的编译器错误,但不是 GCC [重复]
【发布时间】:2018-07-11 11:28:43
【问题描述】:

在帮助解决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 我不需要解决这些问题的方法,因为它非常简单。我只想知道“谁是对的”

【问题讨论】:

    标签: c++ templates language-lawyer


    【解决方案1】:

    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的实参,即使它只需要两个模板参数。

    【讨论】:

    • 我不明白为什么有些人(比如谷歌的 Android 人员)强制使用像 Clang 这样有严重缺陷、显然无用的 C++ 实现,尽管人类有一个工作......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-13
    • 2014-12-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多