Specialisation of class with template template parameter working in clang but not in gcc

Viewed 33

I am trying to make my code, already working on clang, compatible with gcc. I have the following main class:

template<typename T, typename...Ts>
class OperatorTypeHelper
{ public:
  using type=T;
};

template<typename...Inputs>
using OperatorType=typename OperatorTypeHelper<Inputs...>::type;

Then I do also have a class:

template<typename ConstType,typename...Inputs>
class ConstantTensor; 

I want to write a specialisation of OperatorTypeHelper so that it takes binary template template argument as first parameter and another one, which should be more specialised, that specifically takes ConstantTensor:

template<typename ConstType,typename...Inputs, typename QRule>
class OperatorTypeHelper<ConstantTensor<ConstType,Inputs...>,QRule >
{ public:
\\ do staff 
};

template<template<class,class>class Binary,typename Left, typename Right, typename...Ts>
class OperatorTypeHelper< Binary< Left, Right >, Ts...>
{ public:
\\ do staff 
};

I obtain, from gcc, an ambiguity error, which clang did not gave me. Indeed also the second specialisation can satisfies the arguments of the first one. On the other hand, I would expect the first one to be accepted. Reading on this website, I found out that, for gcc and the standard, does not seem to be the case. I also have read about the dummy argument, but I do not know to apply that since I also have variadic templates.

I would like to solve this kind of issue, if it possibile, without modifying too much the code. Or at least to have a workaround.

Here a working example (which I forgot and thaks super for this):

https://godbolt.org/z/VDAaLD

#include <functional>
#include <map>
#include <string>

template<typename T, typename...Ts>
class OperatorTypeHelper
{ public:
  using type=T;
};


template<typename ConstType,typename...Inputs>
class ConstantTensor {};

template<typename ConstType,typename...Inputs, typename QRule>
class OperatorTypeHelper<ConstantTensor<ConstType,Inputs...>,QRule >
{ public:
// do staff 
};

template<template<class,class>class Binary,typename Left, typename Right, typename...Ts>
class OperatorTypeHelper< Binary< Left, Right >, Ts...>
{ public:
// do staff 
};

template <typename L, typename R>
struct Bin {};

int main() {
    OperatorTypeHelper<ConstantTensor<int, int>, int> i;
    OperatorTypeHelper<Bin<int, int>, int> i2;
}
0 Answers
Related