Клонирование типа?

В C ++ два типа могут иметь такое же определение без того же типа.

Например, рассмотрим A а также B Вот:

struct A {
int foo;
int bar;
};

struct B {
int foo;
int bar;
};

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

A а также B являются взаимозаменяемыми в том смысле, что, если бы у меня была программа, которая
используется только Aи заменил каждый экземпляр A с Bбыло бы скомпилировать
и работать так же. Если хотите, они одинаковы в смысле «утки», но не идентичны.

Нечто подобное происходит с некоторыми фундаментальными типами.

Когда я компилирую программы C ++ на моей 32-битной машине, я обнаруживаю, что int а также long оба представляют 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 не правильно делает (int а также long предполагается
быть отличным, даже если они имеют одинаковый размер), это не может быть
это работает — должен быть какой-то другой механизм.


Этот вопрос на самом деле не о деталях реализации компилятора: скорее,
Вопрос в том, есть ли способ на уровне пользователя, стандартный 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, "");

?

(У меня нет особого смысла, это просто любопытство.)

1

Решение

Вы можете использовать шаблоны для этого:

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

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

Сюда A а также B бывают разных типов, но это позволяет вам делать столько, сколько вы хотите, без повторения определения.

3

Другие решения

Вы можете просто наследовать:

struct A {
int foo;
int bar;
};

struct B : A{};

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

живой пример

Вы все еще можете использовать свой 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};
}

живой пример

3

По вопросам рекламы [email protected]