Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

More specific template deduction

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.

like image 691
toozyfuzzy Avatar asked Aug 30 '26 07:08

toozyfuzzy


1 Answers

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.

like image 189
Barry Avatar answered Aug 31 '26 21:08

Barry



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!