[英]SFINAE for an non-member operator overload
我有一个非成员运算符重载,我需要对其应用 SFINAE 以使其正常工作。 我在实施过程中遇到了困难,在网上寻找参考资料时找不到与我需要的类似的东西,我知道我花了一天的大部分时间试图让它工作但无济于事,希望能得到一些帮助社区。 基本上对于第一个操作数重载我需要 SFINAE 类型 std::is_arithmetic 和第二个需要 SFINAE 类型
并键入 std::is_class。 或者,如果您对下面的代码有任何其他建议,我们将不胜感激。 预先感谢您的帮助。
template <typename T>
class Matrix3D
{
public:
//////////////////////////////////////////////////////////////////////////
// *** CONSTRUCTORS ***
//////////////////////////////////////////////////////////////////////////
/// Default Constructor
//
Matrix3D(void);
/// External initialization Constructor
//
Matrix3D(const T& p_11, const T& p_12, const T& p_13,
const T& p_21, const T& p_22, const T& p_23,
const T& p_31, const T& p_32, const T& p_33);
....
/// Vector division by matrix eqv to [M]^-1 * {V}
/// \param p_vector p_matrix
/// SFINAE enable_if type V std::is_arithmetic
//
template <typename U, typename V>
friend Vector3D<decltype(std::declval<U>() / std::declval<V>())> operator/ (const Vector3D<U>& p_vector, const Matrix3D<V>& p_matrix);
/// Vector division by matrix eqv to [M]^-1 * {V}
/// \param p_vector p_matrix
/// SFINAE enable_if type P && type Q std::is_class
//
template <typename P, typename Q>
friend Vector3D<decltype(std::declval<P>() / std::declval<Q>())> operator/ (const Vector3D<P>& p_vector, const Matrix3D<Q>& p_matrix);
....
private:
//////////////////////////////////////////////////////////////////////////
// *** PRIVATE METHODS ***
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// *** PRIVATE DATA MEMBERS ***
//////////////////////////////////////////////////////////////////////////
/// Matrix m_elements
//
std::array<std::array<T, 3>, 3> m_elem;
}
/// Vector division by matrix eqv to [M]^-1 * {V}
/// \param p_vector p_matrix
/// SFINAE enable_if type V std::is_arithmetic
//
template <typename U, typename V>
Vector3D<decltype(std::declval<U>() / std::declval<V>())> operator/ (const Vector3D<U>& p_vector, const Matrix3D<V>& p_matrix)
{
Matrix3D<V> matrixinv = p_matrix.Inverse();
return static_cast<Vector3D<decltype(std::declval<U>() / std::declval<V>())>> (matrixinv * p_vector);
}
/// Vector division by matrix eqv to [M]^-1 * {V}
/// \param p_vector p_matrix
/// SFINAE enable_if type P && type Q std::is_class
//
template <typename P, typename Q>
Vector3D<decltype(std::declval<P>() / std::declval<Q>())> operator/ (const Vector3D<P>& p_vector, const Matrix3D<Q>& p_matrix)
{
Matrix3D<Q> matrixinv = p_matrix.Inverse();
Matrix3D<double> dmatrixinv(matrixinv.m_elem[0][0].Get(), matrixinv.m_elem[1][0].Get(), matrixinv.m_elem[2][0].Get(),
matrixinv.m_elem[0][1].Get(), matrixinv.m_elem[1][1].Get(), matrixinv.m_elem[2][1].Get(),
matrixinv.m_elem[0][2].Get(), matrixinv.m_elem[1][2].Get(), matrixinv.m_elem[2][2].Get());
Vector3D<double> dvector(p_vector.GetX().Get(), p_vector.GetY().Get(), p_vector.GetZ().Get());
Vector3D<double> dres = dmatrixinv * dvector;
decltype(std::declval<U>() / std::declval<V>()) elem[3];
return Vector3D<decltype(std::declval<U>() / std::declval<V>())>(elem[0].Set(dres.GetX()), elem[1].Set(dres.GetY()), elem[2].Set(dres.GetZ()));
}
您可以添加std::enable_if_t<your_condition<U, V>::value, int> = 0
作为模板参数:
/// Vector division by matrix eqv to [M]^-1 * {V}
/// \param p_vector p_matrix
/// SFINAE enable_if type V std::is_arithmetic
//
template <typename U,
typename V,
std::enable_if_t<std::is_arithmetic<V>::value, int>/* = 0*/>
friend Vector3D<decltype(std::declval<U>() / std::declval<V>())>
operator/ (const Vector3D<U>& p_vector, const Matrix3D<V>& p_matrix);
/// Vector division by matrix eqv to [M]^-1 * {V}
/// \param p_vector p_matrix
/// SFINAE enable_if type P && type Q std::is_class
//
template <typename P,
typename Q,
std::enable_if_t<std::is_class<P>::value && std::is_class<Q>::value, int> /* = 0*/>
friend Vector3D<decltype(std::declval<P>() / std::declval<Q>())>
operator/ (const Vector3D<P>& p_vector, const Matrix3D<Q>& p_matrix);
或在 C++20 中,您可能会使用requires
:
template <typename U, typename V>
friend Vector3D<decltype(std::declval<U>() / std::declval<V>())>
operator/ (const Vector3D<U>& p_vector, const Matrix3D<V>& p_matrix)
requires(std::is_arithmetic<V>::value);
template <typename P, typename Q>
friend Vector3D<decltype(std::declval<P>() / std::declval<Q>())>
operator/ (const Vector3D<P>& p_vector, const Matrix3D<Q>& p_matrix)
requires(std::is_class<P>::value && std::is_class<Q>::value);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.