C ++:如何复制数据类型?

时间:2018-04-25 09:36:45

标签: c++ types

我想使用具有不同名称的数据类型(创建类型的副本)。 我不想使用' typedef'因为它只会像别名一样创建#define /宏。

#include <iostream>

typedef int AnInt;

struct Number
{
    int a;
};

template<typename T>
T var;

int main()
{
    var<int> = 5;
    var<AnInt> = 7; // does not what i want (this changes var<int>)
    var<Number>.a = 7;
    return 0;
}

这正是我希望它工作的方式,但我总是需要使用postfix .a来访问该类型。 有没有办法避免这种情况?

编辑:

真实世界的应用程序是我有一个vec3数据类型,现在我需要不同的数据类型PositionVelocity,它们本质上是一个vec3。它们需要不同,因为我使用的是基于模板的实体组件系统。

3 个答案:

答案 0 :(得分:3)

创建一个与原始布局完全相同的新的非隐式可转换类型的最简单方法是继承:

struct Position: vec3 {};
struct Velocity: vec3 {};

请注意,它们仍然可以隐式转换为vec3d&,而不是相互转换。

答案 1 :(得分:2)

由于typedef只是为类型创建别名(不是宏),因此您需要创建一个新类型来表示其新标识。由于您希望对值的访问尽可能平滑,因此您可以定义一个新类并重载某些运算符:

template <class T>
class wrapper
{
    T value;
public:
    wrapper()
    {

    }

    wrapper(T &&obj) : value(std::move(obj))
    {

    }

    wrapper(const T &obj) : value(obj)
    {

    }

    operator T&()
    {
        return value;
    }

    operator const T&() const
    {
        return value;
    }

    T &operator*()
    {
        return value;
    }

    const T &operator*() const
    {
        return value;
    }

    const T &operator->() const
    {
        return value;
    }

    T &operator->()
    {
        return value;
    }
};

如有必要,添加更多运算符。然后,每个新类型都将继承此类:

struct new_int : public wrapper<int>
{
    new_int()
    {

    }

    new_int(int &&obj) : wrapper<int>(std::move(obj))
    {

    }

    new_int(const int &obj) : wrapper<int>(obj)
    {

    }
};

您可以创建一个有助于构建这些类型的宏:

#define new_type(name, base) struct name : public wrapper<base> { \
    name() {} \
    name(base &&obj) : wrapper<base>(std::move(obj)) {} \
    name(const base &obj) : wrapper<base>(obj) {} \
}

所有这些新类型将彼此不同:

new_type(new_int1, int);
new_type(new_int2, int);

int main()
{
    var<int> = 12;
    var<wrapper<int>> = 13;
    var<new_int1> = 14;
    var<new_int2> = 15;
    std::cout << var<int> << std::endl;
    std::cout << var<wrapper<int>> << std::endl;
    std::cout << var<new_int1> << std::endl;
    std::cout << var<new_int2> << std::endl;
}

答案 2 :(得分:0)

如果您想确保类型安全,请尝试foonathan/type_safe。这是一个仅限标头的库,它使用标准C ++提供了opaque typedef仿真的机制:

  

type_safe提供使用C ++类型的零开销抽象   系统,以防止错误。

     
    

零开销抽象在这里和以下平均抽象中没有成本且启用了优化,但可能导致轻微

  
     

在调试模式下降低运行时间,尤其是在断言时   库已启用。

     

库功能无法在此范围内真正解释   自述,我强烈建议您查看firstsecond博客   发布和示例。

如果您只需要对涉及物理的东西使用强类型定义,请查看Boost.Units

  

Boost.Units库是维度的C ++实现   以一般和可扩展的方式进行分析,将其视为通用的   编译时元编程问题。用适当的编译器   优化,没有引入运行时执行成本,便于实现   使用此库提供维度检查   性能关键代码。支持单位和数量(定义   作为一个单位和相关的价值)任意单位系统模型和   提供了任意值类型,细粒度通用也是如此   单位转换设施。完整的SI和CGS单元系统   提供,以度为单位测量的角度系数,弧度,   测量温度的梯度,旋转和系统   开尔文,摄氏度和华氏度。图书馆   体系结构的设计具有灵活性和可扩展性   心神;展示了添加新单位和单位的便利性   转换在示例中提供。

P.S。如果你想要一些代码示例,请告诉我。