Search code examples
c++gccg++clangclang++

Specialize template template parameter with a non-type template parameter


I'm trying to have partial specialization of a class template, where one template parameter is a template template parameter containing a single non-type parameter. For example:

template <
    class T, 
    template <class Result, Result> class BinaryOperation
>
struct Foo;

template <
    template <class Result, Result> class BinaryOperation
>
struct Foo<
    int,
    BinaryOperation
>
{ };

This code compiles fine using GCC-4.9.2.

However, using Clang-4.0, I get a cryptic error message:

$ clang++-4.0 test.cpp -o test -std=c++14 -stdlib=libc++ 
test.cpp:18:3: error: template template argument has different template parameters than its corresponding template template
      parameter
                BinaryOperation
                ^
test.cpp:14:33: note: template non-type parameter has a different type 'Result' in template argument
                template <class Result, Result> class BinaryOperation
                                              ^
test.cpp:9:33: note: previous non-type template parameter with type 'Result' is here
                template <class Result, Result> class BinaryOperation

I've been Googling around for this error message, but it's very unclear to me. It seems to be saying that Result is somehow considered a different type when it appears as a template parameter versus when it appears as one of the arguments to the specialization list.

It works on GCC-4.9.2, so I don't know if this is a problem with Clang 4, or if GCC-4.9.2 is allowing something that it shouldn't.

So why does Clang-4 report this compiler error?


Solution

  • There is a bug reported on Clang bugzilla for this titled: Alias template produces seemingly bogus "template template argument has different template parameters" error

    This bug can be resolved in Clang 4 with the compiler option -frelaxed-template-template-args.

    See demo here.

    This has been fixed in later versions of Clang (from 5.0.0 onwards).