克隆一种类型?

时间:2016-08-06 14:42:55

标签: c++ templates types typedef substitution

在C ++中,两种类型可以具有相同的定义而不是相同的类型。

例如,请在此处考虑AB

struct A {
  int foo;
  int bar;
};

struct B {
  int foo;
  int bar;
};

static_assert(!std::is_same<A, B>::value, "");
如果我有一个程序,那么

AB是可以互换的 仅使用A,并将A的每个实例替换为B,它将进行编译 并以同样的方式工作。如果你愿意,它们在“鸭子打字”的意义上是相同的,但不相同。

某些基本类型似乎发生了类似的事情。

当我在32位机器上编译C ++程序时,我发现intlong都代表一个带符号的32位整数,并且可以互换,但不是同一类型。

这与我使用typedef“复制”类型时发生的情况不同。

struct A {
  int foo;
  int bar;
};

typedef A B;

static_assert(std::is_same<A, B>::value, "");

typedef不会创建新类型,它会为同一类型创建新名称, 好像。

天真地,人们可能会想象典型的编译器使用某种编译器内在函数 实现基本类型。例如,你可能会想到有一些 排序模板__signed_integer,然后在一些内部头文件中, 你找到这样的东西

typedef __signed_integer<4> int;
typedef __signed_integer<4> long;

在不同的实现方式上会有所不同。

但是,由于typedef没有做正确的事(intlong是假设的 为了区别,即使它们具有相同的大小),这实际上并不是如何 它有效 - 必须有其他机制。

这个问题实际上并不是关于编译器实现的细节:相反, 问题是,在用户级标准C ++中是否存在“typedef”类型的方法 以某种方式制作副本而不是别名?

即。有没有办法获得与代码相同的效果:

struct A {
  int foo;
  int bar;
};

struct B {
  int foo;
  int bar;
};

static_assert(!std::is_same<A, B>::value, "");

但没有写两次定义,而是编写类似

的内容
struct A {
  int foo;
  int bar;
};

typedef clone<A> B;

static_assert(!std::is_same<A, B>::value, "");

(我没有特别的用处,这只是一种好奇心。)

2 个答案:

答案 0 :(得分:3)

您可以简单地继承:

struct A {
  int foo;
  int bar;
};

struct B : A{};

static_assert(!std::is_same<A, B>::value, ""); 

live example

如果您愿意,仍然可以使用clone

#include <type_traits>
#include <utility>

struct A {
  int foo;
  int bar;
};

template <typename T>
struct clone : public T
{
   using T::T;
   template<typename ...Ts>
   clone(Ts&&...ts):T{ std::forward<Ts>(ts)... } {};
};

using B = clone<A>;

static_assert(!std::is_same<A, B>::value, ""); 

int main()
{
    A a{1,2};
    B b{1,2};
}

live example

答案 1 :(得分:3)

您可以使用模板:

template <int>
struct foobar {
  int foo;
  int bar;
};

using A = foobar<1>;
using B = foobar<2>;

这种方式AB是不同的类型,但它允许您根据需要制作任意数量而不重复定义。