与模板化函数一起使用时,不会对模板化结构进行隐式转换

时间:2019-05-20 21:54:17

标签: c++

考虑以下代码示例:

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

1 个答案:

答案 0 :(得分:1)

给出代码以调用该函数

foo<double> a;
foo<float>  b;

bar(a, b);

编译器无法确定Tdouble还是float。两者都是同样好的候选人。因此,它无法解析类型。

您可以使用以下方式之一解决问题:

  1. 在通话中明确显示T

    bar<double>(a, b);
    
  2. 更改函数声明,以便有两种类型,除非明确指定,否则从第一个参数推导出第一个类型,从第一个参数推导第二个类型。

    template<typename T1, typename T2 = T1>
    void bar(foo<T1> a, foo<T2> b)
    {
        //
    }
    

    然后,您可以使用

    bar(a, b);
    

    如果要保留类型foo<float>的第二个参数,则必须对此明确。

    bar<double, float>(a, b);