更具体的模板扣除

时间:2018-03-27 15:41:33

标签: c++ templates variadic-templates c++17 template-specialization

我有主要模板和三个部分特化,编译器认为它们不明确:

#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
}

我使用g ++ 7.3.0和-std = c ++ 17。

如果我们按照评论中的建议为第一次专业化中的两个容器提供allocators参数,那么一切正常。

1 个答案:

答案 0 :(得分:1)

我们有三个匹配的特化(感谢允许使用默认参数的new rules in C++17):

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>)

其中哪一个比其他更专业?好吧,#1比#2更专业(因为任何单个参数在#2中起作用,但只有一个参数的类模板特化在#1中起作用),所以这很好。

但#1和#3都不是更专业的 - A采用不同数量的模板参数,因此不起作用。并且#2和#3都不是更专业 - 出于同样的原因。

由于您无法说出哪些专门针对这些案例,因此扣除不明确。你真的可以指任何一个。

您需要重新考虑您在此处所做的专业化。