模板之间的隐式转换



我不太明白为什么此处的代码不编译。应该可以像这样致电dist((:

dist(GenericVec2<T>,GenericVec3<T>)

(这可能是多可怕的(。这个想法是,genericVec3参数被转换操作员隐式转换为genericVec2。我在这里找到了这个问题

C 隐式类型转换使用模板

,但是我不确定是否可以将其应用于我的问题(将转换操作员设置为" friend"不起作用(。VS输出以下错误:

error C2672: 'dist': no matching overloaded function found
error C2784: 'F dist(const GenericVec2<F> &,const GenericVec2<F> &)': could not deduce template argument for 'const GenericVec2<F> &' from 'Vec3'
note: see declaration of 'dist'

这是我的代码:

#include <iostream>
template<typename F> struct GenericVec2
{
    GenericVec2<F>::GenericVec2(F _x = 0, F _y = 0) : x(_x), y(_y) {}
    F x;
    F y;
};
using Vec2 = GenericVec2<float>;
template<typename F> struct GenericVec3
{
    GenericVec3<F>::GenericVec3(F _x = 0, F _y = 0, F _z = 0) : x(_x), y(_y), z(_z) {}
    operator GenericVec2<F>()               { return *reinterpret_cast<GenericVec2<F>*>(&x); }
    operator const GenericVec2<F>() const   { return *reinterpret_cast<const GenericVec2<F>*>(&x); }
    F x;
    F y;
    F z;
};
using Vec3 = GenericVec3<float>;
template<typename F> F dist(const GenericVec2<F>& a, const GenericVec2<F>& b)
{
    return std::hypot(a.x - b.x, a.y - b.y);
}
int main()
{
    Vec2 a{ 2.0f, 3.0f };
    Vec3 b{ 1.0f, 1.0f, 1.0f };
    Vec2 c = b;
    float d = dist(a, Vec2{ b });   // works
    float e = dist(a, b);           // doesn't compile
    std::cin.ignore();
    return 0;
}

预先感谢!

- thomas

问题是,在

template<typename F> F dist(const GenericVec2<F>& a, const GenericVec2<F>& b)

您无法从GenericVec2<float>推导第二个参数。一种解决方案是通过friend使功能非模板:

template<typename F> struct GenericVec2
{
    GenericVec2<F>::GenericVec2(F _x = 0, F _y = 0) : x(_x), y(_y) {}

    friend F dist(const GenericVec2& a, const GenericVec2& b)
    {
        return std::hypot(a.x - b.x, a.y - b.y);
    }
    F x;
    F y;
};

要进行隐式转换,目标类应具有接收源类型(或从源类型转换的类型(作为参数的构造函数。GenericVec3中定义的铸造操作员用于显式铸造操作。

因此,您应该在GenericVec2类中定义以下构造函数

GenericVec2(const GenericVec3<F>& v3) { ... }

最新更新