Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/124.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vue.js/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++:如何复制数据类型?_C++_Types - Fatal编程技术网

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

C++:如何复制数据类型?,c++,types,C++,Types,我想使用具有不同名称的数据类型创建类型的副本。 我不想使用“typedef”,因为这只会创建一个像别名一样的define/macro #include <iostream> typedef int AnInt; struct Number { int a; }; template<typename T> T var; int main() { var<int> = 5; var<AnInt> = 7; // does

我想使用具有不同名称的数据类型创建类型的副本。 我不想使用“typedef”,因为这只会创建一个像别名一样的define/macro

#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;
}
这正是我希望它的工作方式,但我始终需要使用后缀访问类型。 有没有办法避免这种情况

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

由于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;
}
由于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;
}

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

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

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

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

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

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

如果要确保类型安全,请尝试。这是一个只包含标题的库,它提供了使用标准C++进行不透明typedef模拟的机制:

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

这里和后面的零开销抽象意味着在启用优化的情况下没有成本,但可能会导致

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

在本文的范围内,无法真正解释库功能 自述文件,我强烈建议您查看 帖子和例子

如果您只需要将强typedef用于涉及物理的内容,请查看:

Boo.UnLoad库是C++的C++实现 以通用和可扩展的方式进行分析,将其视为通用 编译时元编程问题。使用适当的编译器 优化,不引入运行时执行成本,便于 使用此库提供维度检入 性能关键代码。支持已定义的单位和数量 作为任意单位系统模型的单位和关联值,以及 提供了任意值类型,细粒度的通用 单位转换设施。完整的SI和CGS单元系统是 提供以度、弧度为单位的角度测量系统, 梯度仪、转数和温度测量系统 开尔文,摄氏度和华氏度。图书馆 体系结构的设计具有灵活性和可扩展性 介意演示添加新单元和单元的简易性 示例中提供了转换


另外,如果您想要一些代码示例,请告诉我。

如果您想确保类型安全,请尝试。这是一个只包含标题的库,它提供了使用标准C++进行不透明typedef模拟的机制:

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

这里和后面的零开销抽象意味着在启用优化的情况下没有成本,但可能会导致

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

在本文的范围内,无法真正解释库功能 自述文件,我强烈建议您查看 帖子和例子

如果您只需要将强typedef用于涉及物理的内容,请查看:

Boo.UnLoad库是C++的C++实现 以通用和可扩展的方式进行分析,将其视为通用 编译时元编程问题。使用适当的编译器 优化,不引入运行时执行成本,便于 使用此库提供维度检入 表演 关键代码。支持已定义的单位和数量 作为任意单位系统模型的单位和关联值,以及 提供了任意值类型,细粒度的通用 单位转换设施。完整的SI和CGS单元系统是 提供以度、弧度为单位的角度测量系统, 梯度仪、转数和温度测量系统 开尔文,摄氏度和华氏度。图书馆 体系结构的设计具有灵活性和可扩展性 介意演示添加新单元和单元的简易性 示例中提供了转换


另外,如果您想要一些代码示例,请告诉我。

您要找的是强类型定义。必须用C++中的类来模拟它,顺便说一句,这看起来像是一个。要么接受与基类型之间的隐式转换,此时它们几乎可以互换,要么到处都有.member。选择一个使用第三方尺寸标注/单位库,如boost::units。您需要的是一个强类型定义。必须用C++中的类来模拟它,顺便说一句,这看起来像是一个。要么接受与基类型之间的隐式转换,此时它们几乎可以互换,要么到处都有.member。选择一个使用第三方标注/单位库,如boost::units.True,这需要更多的工作,但问题确实提到了我假设为UDT的vec3。我明白了。我没有注意到编辑,因此我假设解决方案必须是所有类型的通用解决方案。没错,这需要更多的工作,但问题确实提到了我假设为UDT的vec3。我明白了。我没有注意到编辑,因此我认为解决方案必须适用于所有类型。NB。包装机只是为了让原语可以遗传。您仍然使用完全相同的继承机制来生成final types.NB。包装机只是为了让原语可以遗传。您仍然使用完全相同的继承机制来生成最终类型。