【问题标题】:user-defined conversion cannot use static_cast in C++用户定义的转换不能在 C++ 中使用 static_cast
【发布时间】:2018-09-11 12:11:37
【问题描述】:

我正在尝试解决 Eigen 的一些问题。过程中发现static_cast自定义转换冲突,可能是std::enable_if的问题?

这基本上是我尝试过的:

#include <Eigen/Dense>
#include <bits/stdc++.h>

using namespace std;

class Vector2
{
public:
    operator Eigen::Vector2d ()
    {   
        return data;
    }   
private:
    Eigen::Vector2d data;
};

class Box2
{
public:
    void Extend(const Vector2 & a)  
    {   
        data.extend( static_cast<Eigen::Vector2d>(a) );     // error, but why?
    }   
private:
    Eigen::AlignedBox2d data;   
};

int main()
{
    Vector2 a;
    Eigen::Vector2d b = a;      // ok, implicit conversion
    return 0;   
}

g++ -std=c++11输出很多错误日志,这是最后一部分:

eigen/eigen/Eigen/src/Core/PlainObjectBase.h:863:30: note:   template argument deduction/substitution failed:
eigen/eigen/Eigen/src/Core/PlainObjectBase.h: In substitution of ‘template<class T> void Eigen::PlainObjectBase<Derived>::_init1(const Index&, typename Eigen::internal::enable_if<((((((! Eigen::internal::is_same<long int, typename Eigen::internal::traits<T>::Scalar>::value) && Eigen::internal::is_same<long int, T>::value) && (typename Eigen::internal::dense_xpr_base<Derived>::type:: SizeAtCompileTime != Eigen::Dynamic)) && (typename Eigen::internal::dense_xpr_base<Derived>::type:: SizeAtCompileTime != 1)) && Eigen::internal::is_convertible<T, typename Eigen::internal::traits<T>::Scalar>::value) && Eigen::internal::is_same<typename Eigen::internal::traits<T>::XprKind, Eigen::ArrayXpr>::value), T*>::type*) [with T = T; Derived = Eigen::Matrix<double, 2, 1>] [with T = Vector2]’:
eigen/eigen/Eigen/src/Core/Matrix.h:296:33:   required from ‘Eigen::Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::Matrix(const T&) [with T = Vector2; _Scalar = double; int _Rows = 2; int _Cols = 1; int _Options = 0; int _MaxRows = 2; int _MaxCols = 1]’
test.cpp:21:52:   required from here
eigen/eigen/Eigen/src/Core/PlainObjectBase.h:863:30: error: invalid use of incomplete type ‘struct Eigen::internal::enable_if<false, Vector2*>’
In file included from eigen/eigen/Eigen/Core:364:0,
                 from eigen/eigen/Eigen/Dense:1,
                 from eigen/eigen/Eigen/Eigen:1,
                 from test.cpp:2:
eigen/eigen/Eigen/src/Core/util/Meta.h:162:50: error: declaration of ‘struct Eigen::internal::enable_if<false, Vector2*>’
 template<bool Condition, typename T=void> struct enable_if;
                                                  ^

好像是enable_if的问题,不知道为什么static_cast不起作用。有没有办法在不修改 Eigen 的情况下解决这个问题?现在可以这样做了:

void Extend(Vector2 a)  
{   
    Eigen::Vector2d b = a;
    data.extend( b );    
} 

但是太丑了。

【问题讨论】:

    标签: c++ type-conversion enable-if


    【解决方案1】:

    好像是enable_if的问题,不知道为什么static_cast没有 工作。

    这与static_cast 本身无关。生成错误是因为Vector2operator Eigen::Vector2d () 没有为const 对象定义,并且由于您的Box2::Extend() 采用const Vector2&amp; a,因此未在代码中为该行定义适当的转换。将Vector2用户定义的转换const 版本添加到Eigen::Vector2d 以使其编译并保留代码的const-correctness

    const operator Eigen::Vector2d () const
    {   
        return data;
    } 
    

    现在用法如您所愿:

    int main()
    {
        Vector2 a;
        Eigen::Vector2d b = a;    // ok, implicit conversion
    
        Box2 boxy;
        boxy.Extend(a);           // also ok, implicit conversion inside, from a const&
    
        return 0;   
    }
    

    【讨论】:

    • @SkepticalEmpiricist 谢谢!我按照您的解决方案解决了它。 C++ 编译错误日志经常误导我。还要在这里感谢其他人。
    • @sfire 请注意,重新考虑后,我进行了编辑以明确正确的解决方案是添加另一个版本的转换运算符,而不是仅仅改变现有的。
    • 好的,我知道了。感谢您提供有关 const 正确性的信息。
    猜你喜欢
    • 2011-09-13
    • 1970-01-01
    • 2018-01-25
    • 1970-01-01
    • 2011-03-05
    • 1970-01-01
    • 1970-01-01
    • 2013-02-24
    • 1970-01-01
    相关资源
    最近更新 更多