考虑以下代码示例:
template<typename T>
struct foo
{
operator foo<double>() const
{
return foo<double>();
}
};
template<typename T>
void bar(foo<T> a, foo<T> b)
{
//
}
int main()
{
foo<double> a;
foo<float> b;
bar(a, b); // error: no matching function
return 0;
}
编译时,由于调用bar
时找不到匹配的函数而产生错误。即使foo<float>
拥有一个对foo<double>
的隐式转换运算符,为什么仍不能正常工作?
void bar_non_template(foo<double> a, foo<double> b) {} // this works
template<>
void bar(foo<double> a, foo<double> b) {} // template specialization doesn't work
如果我要对模板参数使用两种类型,则它可以工作,但我想在正在编写的3d向量类中使用它,并且我担心函数的返回类型会丢失数据。示例:
template<typename T, typename U>
vec3d</* T or U? one is possible loss of data */> operator + (
const vec3d<T> &lhs, const vec3d<U> &rhs) {...}
所以我的另一个问题是,是否有可能确定两种给定类型中哪个更广泛/更准确?
编辑:
编译器错误:
g ++:
error: no matching function for call to 'bar(foo<double>&, foo<float>&)'
note: candidate: template<class T> void bar(foo<T>, foo<T>)
note: template argument deduction/substitution failed:
note: deduced conflicting types for parameter 'T' ('double' andd 'float')
vc ++:
error C2672: 'bar': no matching overloaded function found
error C2782: 'void bar(foo<T>, foo<T>)': template parameter 'T' is ambiguous
error C2784: 'void bar(foo<T>, foo<T>)': could not deduce template argument for 'foo<T>' from 'foo<float>'
答案 0 :(得分:1)
给出代码以调用该函数
foo<double> a;
foo<float> b;
bar(a, b);
编译器无法确定T
是double
还是float
。两者都是同样好的候选人。因此,它无法解析类型。
您可以使用以下方式之一解决问题:
在通话中明确显示T
。
bar<double>(a, b);
更改函数声明,以便有两种类型,除非明确指定,否则从第一个参数推导出第一个类型,从第一个参数推导第二个类型。
template<typename T1, typename T2 = T1>
void bar(foo<T1> a, foo<T2> b)
{
//
}
然后,您可以使用
bar(a, b);
如果要保留类型foo<float>
的第二个参数,则必须对此明确。
bar<double, float>(a, b);