Есть ли идиома для строгого определения типа в C ++, возможно, с использованием шаблонов?
Что-то вроде:
template <class base_type, int N> struct new_type{
base_type p;
explicit new_type(base_type i = base_type()) : p(i) {}
};
typedef new_type<int, __LINE__> x_coordinate;
typedef new_type<int, __LINE__> y_coordinate;
Так что я могу сделать что-то вроде этой ошибки времени компиляции:
x_coordinate x(5);
y_coordinate y(6);
x = y; // whoops
__LINE__
похоже, это может быть проблемой, но я бы предпочел не создавать вручную набор констант, просто чтобы сохранить каждый тип уникальным.
Я использую нечто подобное в моем проекте. Только я использую маркировку типа вместо int. Хорошо работает в моем конкретном приложении.
template <class base_type, class tag> class new_type{
public:
explicit new_type(base_type i = base_type()) : p(i) {}
//
// All sorts of constructors and overloaded operators
// to make it behave like built-in type
//
private:
base_type p;
};
typedef new_type<int, class TAG_x_coordinate> x_coordinate;
typedef new_type<int, class TAG_y_coordinate> y_coordinate;
Обратите внимание, что классы TAG_ * не нужно нигде определять, это просто теги
x_coordinate x (1);
y_coordinate y (2);
x = y; // error
Нет. Есть предложения перейти к следующему стандарту (C ++ 14 или, возможно, C ++ 17), но не в C ++ 11.
С С ++ 11:
#include <stdio.h>
struct dummy {};
struct NotMineType
{
NotMineType(dummy) {}
};
template <int N>
struct type_scope
{
struct MyOwnType
{
};
struct ConvertedToMineType : NotMineType
{
template <typename ...Args>
ConvertedToMineType(Args... args) : NotMineType(args...) {};
};
enum myint : int {};
};
typedef type_scope<0>::MyOwnType x1;
typedef type_scope<1>::MyOwnType x2;
typedef type_scope<0>::ConvertedToMineType y1;
typedef type_scope<1>::ConvertedToMineType y2;
typedef type_scope<0>::myint i1;
typedef type_scope<1>::myint i2;
void foo(x1) { printf("x1\n"); }
void foo(x2) { printf("x2\n"); }
void foo(y1) { printf("y1\n"); }
void foo(y2) { printf("y2\n"); }
void foo(i1) { printf("i1\n"); }
void foo(i2) { printf("i2\n"); }
int main()
{
foo(x1());
foo(x2());
foo(y1(dummy()));
foo(y2(dummy()));
foo(i1());
foo(i2());
}
Выход:
x1
x2
y1
y2
i1
i2
Составители:
Visual Studio 2015, GCC 4.8.x