代码之家  ›  专栏  ›  技术社区  ›  Soonts

有可能实现自动全局强制转换吗?

c++
  •  1
  • Soonts  · 技术社区  · 5 年前

    我有多个依赖项,它们定义了完全相同的数据结构。

    例如, DirectX::XMFLOAT3 std::array<float,3> 来自STL, openvdb::v6_1::math::Vec3s 来自VDB, gte::Vector3<float> 来自GTEngine, Eigen::Vector3f 根据Eigen,它们有100%兼容的内存布局,即sizeof=12,alignof=4,保存3个浮点值。我在一个项目中使用所有这些库,这不是一个完整的列表,我有更多。

    有没有办法实现一些全局会话操作符,或者可能是预处理器欺骗,允许C++编译器透明地跨所有这些类型?

    我不愿意修改任何这些库的源代码,太冒险,太多的工作。

    目前Im正在进行内联函数转换。但是,随着库数量的增加,工作量以O(N^2)的形式增长。此外,我不喜欢既不执行也不调用这些内联函数,它不做任何有用的事情,只是绕过C++类型检查器,并浪费我的源代码。

    1 回复  |  直到 5 年前
        1
  •  1
  •   Nikos C.    5 年前

    通常您只需编写转换运算符重载,但不幸的是它们不能是全局的。 They must be members .

    一种方法可以是编写您自己的类型,该类型可以与所有这些不同类型进行转换,然后使用它。例如,想象一下 Type1 Type2 在这个例子中是外部类型(比如 XMFLOAT3 gte::Vector3<float> ). 然后你就可以自己写一个类型了 MyType 它包含相同的信息,但可以在其他两个文件之间进行转换。这是一个最小的例子:

    struct Type1 {
        double x;
        double y;
        double z;
    };
    
    struct Type2 {
        double x;
        double y;
        double z;
    };
    
    struct MyType {
        double x_;
        double y_;
        double z_;
    
        MyType(double x, double y, double z)
            : x_(x), y_(y), z_(z)
        {}
    
    
        MyType(const Type1& t1)
            : x_(t1.x) , y_(t1.y) , z_(t1.z)
        { }
    
        MyType(const Type2& t2)
            : x_(t2.x) , y_(t2.y) , z_(t2.z)
        { }
    
        operator Type1() const
        {
            return Type1{x_, y_, z_};
        }
    
        operator Type2() const
        {
            return Type2{x_, y_, z_};
        }
    };
    

    然后你就能写下:

    // External APIs
    void func1(Type1);
    void func2(Type2);
    Type1 getT1();
    Type2 getT2();
    
    int main()
    {
        MyType my_type(0, 0, 0);
        Type1 t1 = my_type;
        Type2 t2 = my_type;
    
        my_type = t1;
        my_type = t2;
    
        func1(my_type);
        func2(my_type);
    
        my_type = getT1();
        my_type = getT2();
    }
    

    这里还有一个重要的警告:我自己从不需要这个,也不知道它是否构成了一些已知的反模式。不管我是否真的同意别人的想法。