2013-02-21 29 views
8

Có một thành ngữ cho một typedef nghiêm ngặt trong C++, có thể sử dụng các mẫu?Thành ngữ cho typedef nghiêm ngặt trong C++

Cái gì như:

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; 

Vì vậy, tôi có thể làm một cái gì đó như thế này một lỗi thời gian biên dịch:

x_coordinate x(5); 
y_coordinate y(6); 

x = y; // whoops 

Các __LINE__ trong đó có vẻ như nó có thể là khó khăn, nhưng tôi không muốn phải tự tạo một tập hợp các hằng số để giữ cho từng loại duy nhất.

+1

Tọa độ không phải là một ứng dụng rất tốt cho việc này. Một sản phẩm của hai tọa độ không phải là một tọa độ, vv Bạn có thể muốn xem Boost.Units thay thế. –

+2

Tôi đã xóa câu trả lời được đề xuất [BOOST_STRONG_TYPEDEF] (http://www.boost.org/doc/libs/1_53_0/libs/serialization/doc/strong_typedef.html), bởi vì dường như nó hoạt động với độ phân giải quá tải nhưng không tạo ra biên dịch lỗi về chuyển nhượng chéo. – Angew

+0

Tôi đặt câu hỏi về giá trị của những gì bạn muốn làm. Điều gì sẽ xảy ra khi bạn muốn thực hiện xoay vòng chẳng hạn? 'x = sin (theta) * y + cos (theta) * x' phải hoàn toàn hợp lệ. –

Trả lời

5

Tôi đang sử dụng thứ gì đó tương tự trong dự án của mình. Chỉ có tôi sử dụng gắn thẻ loại thay vì int. Hoạt động tốt trong ứng dụng cụ thể của tôi.

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; 

Lưu ý rằng TAG_ * lớp không cần phải được xác định ở bất cứ đâu, họ chỉ là thẻ

x_coordinate x (1); 
y_coordinate y (2); 

x = y; // error 
+0

Tôi nghĩ rằng điều này sẽ đẹp hơn với một đơn giản "#define new_type (cơ sở, thẻ) typedef new_type <## base, lớp TAG _ ## tag> tag;" – slacy

+1

@slacy dunno, tôi thấy các macro xấu xí và tránh chúng –

2

No. Không có đề xuất cho nó để đi vào tiêu chuẩn tiếp theo (C++ 14, hoặc có lẽ C++ 17), nhưng không phải trong C++ 11.

+1

-1: Anh ta không hỏi liệu nó có trong ngôn ngữ hay không, và có _are_ cách để làm điều đó trong "không gian người dùng ". Do đó, câu trả lời này là không chính xác. –

+0

Không có cách nào để thực hiện nó trong không gian người dùng giống với tính năng ngôn ngữ đang được đề xuất. – Puppy

+0

Điều gì tương tự như những gì được nêu trong câu hỏi? Bây giờ câu trả lời của Angew đã bị vô hiệu, tôi mở ra khả năng, nhưng yêu cầu đầu vào của bạn ở đây. –

0

Với C++ 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()); 
} 

Output:

x1 
x2 
y1 
y2 
i1 
i2 

Trình biên dịch:

Visual Studio 2015, GCC 4.8.x

Các vấn đề liên quan