这应该是可变参数模板的常见情况,例如当作为可变参数模板参数的树行走子级时。我找到了许多相关的问题和答案,但它们要么是关于稍微不同的事情,要么是相同的事情,我没有得到它。现在来解决问题。我有一个像这样的非可变元组
template <class E, class T1, class T2, class T3, etc...>
struct X;
并且我正在重载函数以具有专门的行为,具体取决于此类元组的第一个元素是指针类型还是向量指针类型。这很好,但如果我将模板参数打包成一个可变参数模板参数,那么重载就会变得模棱两可。这是错误消息:
variadic.cpp:42:17: error: ambiguous overload for ‘operator<<’ in ‘std::cout << y’
variadic.cpp:42:17: note: candidates are:...
编译器在尝试匹配元组的第一个元素时应该X<vector<V*>*,T*...>
优先考虑。X<H*,T*...>
vector<double*>*
我可以使用 enable_if 来消除歧义,然后一切都恢复正常了。但是我想了解这个错误,如果可能的话找到其他方法然后 enable_if。这是代码:
#include <iostream>
#include <vector>
#include <boost/type_traits/is_fundamental.hpp>
#include <boost/utility/enable_if.hpp>
using namespace std;
template <typename ... T>
struct X;
template <>
struct X <>
{
};
template <typename H, typename ... T>
struct X<H*,T*...> : public X<T*...>
{
H* value;
X(H* value, T*... args)
: value(value), X<T*...>(args...)
{
}
};
template <typename H, typename ... T>
#ifdef DO_NOT_WANNA_SEE_THE_BUG
typename boost::enable_if<boost::is_fundamental<H>, std::ostream>::type&
operator<<(std::ostream& stream, X<H*,T*...> const & x)
#else
std::ostream& operator<<(std::ostream& stream, X<H*,T*...> const & x)
#endif
{
return stream << "specialized scalar pointer";
}
template <typename V, typename ... T>
std::ostream& operator<<(std::ostream& stream, X<vector<V*>*,T*...> const & x)
{
return stream << "specialized vector pointer";
}
int main()
{
double a,b;
vector<double *> v;
X<double*,double*> x (&a,&b);
X<vector<double*>*, double*> y (&v, &b);
cout << x << endl;
cout << y << endl; // this line is ambiguous according to gcc 4.6 and later
}