I have primary template and three partial specializations, that the compiler considers as ambiguous:
#include <vector>
template<typename ... ARGS>
struct queryBuilder;
template<typename INTERNALDATA,
template<typename> typename ICONTAINER,
template <typename> typename ECONTAINER>
struct queryBuilder<ECONTAINER<ICONTAINER<INTERNALDATA>>>
{ };
template<typename PARAM,
template<typename> typename T>
struct queryBuilder<T<PARAM>>
{ };
template<typename PARAM1,
typename PARAM2,
template<typename,typename> typename T>
struct queryBuilder<T<PARAM1, PARAM2>>
{ };
template<typename T>
struct queryBuilder<T>
{ };
int main() {
queryBuilder<std::vector<std::vector<int>>> q; // error: ambiguous
}
I'm using g++ 7.3.0 with -std=c++17.
Everything works just fine if we, as suggested in comments, provide allocators parameters for both containers in first specialization.
We have three specializations that match here (thanks to new rules in C++17 that allow using default arguments):
1) A<B<C>> (with A = std::vector, B = std::vector, C = int)
2) A<B> (with A = std::vector, B = std::vector<int> )
3) A<B,C> (with A = std::vector, B = std::vector<int>, C = std::allocator<int>)
Which of these is more specialized than the others? Well, #1 is more specialized than #2 (since any single parameter works in #2 but only class template specializations with one parameter work in #1), so that's good.
But neither #1 nor #3 is more specialized - the As take different numbers of template parameters so that just doesn't work. And neither #2 nor #3 is more specialized - for the same reason.
Since you can't say which is the most specialized of these cases, deduction is ambiguous. You could really mean any of them.
You need to rethink the specializations you're doing here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With