我写了一个小型的自包含库(仅依赖于 C++ 标准库),它有自己的内置 3D 矢量类:
namespace mylibrary {
struct Vector {
double x, y, z;
// and constructors
// like:
Vector(double x, double y, double z);
// and operators
};
}
它应该与产生/使用 3D 矢量的其他代码交互。
现在,假设其他一些库,它具有:
namespace otherlibrary {
struct Vector3 {
// some different definition
// And is still able to construct from 3 values
Vector3(double x, double y, double z);
};
doSomething(const Vector3& point); // do something with the point
}
这个其他库可以是 3D 建模工具或 3D 引擎的插件 API。它也有 3D 向量的概念,但它当然是与我的库的向量不同的类型,即使语义相同。想想 Python 的鸭子类型:只要它以预期的方式运行,类型并不重要。
问题:
我可以使用什么机制来方便地使用我的库Vector
作为参数otherlibrary::doSomething()
?
也就是说,能够这样写:
otherlibrary::doSomething( mylibrary::Vector(...) );
我当然可以构建我的Vector
类,使其具有一个模板化的构造函数,该构造函数接受具有“x、y、z”成员或 的任何类型 T operator[]
,因此它几乎可以使用任何可以解释为 3D 向量的东西。有没有可能反过来做呢?
编辑:
当然,我可以让它依赖于另一个库,然后我可以重用另一个库的 3D 矢量抽象。这是不合理的,因为我的库是通用的,所以说使用 Eigen::Vector3d 作为我的向量是没有意义的,因为它可以在不使用 Eigen 的环境中使用。
最佳答案:
根据尼尔柯克的回答:
struct Vector {
using value_type = double;
template<class T,
class = typename enable_if<
is_constructible<T, value_type,value_type,value_type>::value
>::type>
operator T() const
{
return T{x, y, z};
}
};
i 用于在enable_if
多个重载函数和运算符可用时解决歧义;Eigen 是需要它的一个实际案例。