【发布时间】:2017-05-31 10:36:14
【问题描述】:
我不太明白为什么这里的代码不能编译。 应该可以像这样调用 dist() :
dist(GenericVec2<T>,GenericVec3<T>)
(无论这多么可怕)。这个想法是 GenericVec3 参数被转换运算符隐式转换为 GenericVec2。 我在这里找到了这个问题
C++ implicit type conversion with template
,但我不确定它是否可以应用于我的问题(将转换运算符设置为“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;
}
提前致谢!
-托马斯
【问题讨论】:
-
您的
reinterpret_cast打破了严格的别名并从union成员中读取,而不是最后分配给的成员也是UB。把那个代码扔掉,从头开始,它已经坏得无法修复了。如果你不明白我为什么这么说,是时候读一本好书了。 -
我不能,这不是我的代码,也不容易交换。我只需要知道如何编译它(最好不要进行明确的
dist(a, Vec2{b})转换。 -
我已经删除了联合,因为它不是实际问题的一部分(而且确实不是很漂亮)。最初的问题仍然存在。
-
如果我在第一条评论中不清楚:此代码完全不正确且非法。让它编译不会让它变得更好根本。此代码不能用于生产、POC 或玩具程序。 (在
union被删除后仍然适用,请参阅严格别名。) -
您不能将用户定义的隐式转换与模板参数推导结合起来。
dist<float>(a, b)也应该可以工作。
标签: c++ templates implicit-conversion conversion-operator