Minimum Example
I have the following struct with a few specializations:
template<size_t ...Tpar>
struct Base{};
struct X{};
struct Y{};
template<typename T, size_t ...Tpar>
struct Spline: Base<Tpar...>{}; // general type
template<typename T>
struct Spline<T>: Base<>{}; // specialization 1
template<typename T, size_t n>
struct Spline<T,n>: Base<n>{}; // specialization 2
template<size_t ...Tpar>
struct Spline<X,Tpar...>: Base<Tpar...>{}; // specialization 3
template<size_t ...Tpar>
struct Spline<Y,Tpar...>: Base<Tpar...>{}; // specialization 4
The implementation bodies are lengthy each, and have been spared for a minimum example.
Error
The following ambiguity arises for X
(and analogously for Y
):
int main(){
Spline<X,56> sx56; // error: compiler cannot decide between spec. 2 and spec. 3.
}
Why the Overloading
I have one customer class code that is supposed to yield a wide range of different bahaviours depending on i) mainly the type and ii) subsequently the existence and value of additional template arguments. I have tried different things and this appeared convenient for what I am trying to do -- until now, where I wish to re-introduce Tpar...
into specializations 3 and 4.
What I expected
I expected that specialization 3 would be used, because X
is a type restriction whereas n
is only an amount specialization.
What I want
I would like to declare that specialization 3 is to be used in this case. Since the implementations of 3 and 4 are huge, I would like to perform this declaration somewhere concisely.
Workaround
If a timely fix was mandatory, I would use the following:
template<typename T,size_t ...Tpar>
using Spline = std::conditional_t< std::is_value_t<T,X> , Spline_Spec3<Tpar...> , /*...*/ >;
But that would be
- error-prone
- difficult to read
- require nested std::conditional_t for X and Y
- require renaming of specialization class names
As proposed by @HolyBlackCat.