Template template argument causes compiler error under Clang but not GCC [duplicate]

天涯浪子 提交于 2019-12-21 10:44:12

问题


While helping with problem noted in too many template parameters in template template argument a question arose in my head: which compiler is right about the compilation in this case:

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+ compiles it with no errors. Clang 6 and later gives errors showing that there is a problem with Operator template passed as template argument:

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.

Obviously, it treats it as 3-arguments template even though the default third argument is supplied. So here is the question, which of the compilers is right? Does standard say anything about such situations?

PS I do not need a workaround for these kinds of problems as it is pretty simple. I just want to know "who is right"


回答1:


Gcc is correct. Clang seems not in accordance with C++17.

Since C++17 (CWG 150), the default template arguments are allowed for a template template argument to match a template template parameter with fewer template parameters.

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 has 3 template parameters, the 3rd one has default value, then it could be used as the argument for template template parameter Op, even it only expects two template parameters.



来源:https://stackoverflow.com/questions/51284346/template-template-argument-causes-compiler-error-under-clang-but-not-gcc

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!