2013-08-25 32 views
7

Câu hỏi liên quan: std::map default value for build-in type - sự khác biệt tinh tế là tôi muốn nhiều hơn để biết liệu giá trị được khởi tạo thành 0 hoặc rác, tôi muốn chỉ định "hàm tạo". Tôi thậm chí không quan tâm nếu nó liên quan đến overhead với định nghĩa lớp, tôi chỉ muốn một kiểu cơ bản "đặc biệt" rõ ràng. Ngay cả một cú pháp cú pháp cũng sẽ làm. Một loại cơ bản không phải là rất dễ dàng để làm điều này cho, nó là toàn bộ công việc của các nhà xây dựng.Tôi có thể tạo kiểu cơ bản C++ tự khởi tạo như thế nào?

Tôi muốn có một hashmap unordered_map<void *, int> nhưng để có tất cả các giá trị mặc định được khởi tạo thành -1 thay vì 0 hoặc rác. Điều này là do zero là một chỉ mục hợp lệ và tôi muốn mặc định khởi tạo với một giá trị chắc chắn không hợp lệ.

Tôi nghĩ rằng tôi nhìn thấy một vài cách cẩu thả này có thể được thực hiện với:

struct minus1 { 
    int i; 
    minus1() i(-1) {} 
}; 
unordered_map<void*, minus1> 

Nhưng tôi không thích điều này vì tôi phải sử dụng .i để truy cập int, và nó thực sự chỉ cần phải được một int.

Được rồi vì vậy có lẽ tôi có thể có bản đồ của tôi xử lý này:

struct PointerToIDHash { 
    std::unordered_map<void *, int> h; 
    PointerToIDHash() { 
     // ctor is powerless to affect the initialized values of future insertions into h 
    } 
}; 

Vâng, tào lao bây giờ tôi có một .h quá. Uhhhh. Tôi có thể kế thừa từ một mẫu không? (nghe có vẻ đáng sợ, nhưng điều này có thể là một cách sạch sẽ nếu nó có thể được kéo ra)

Làm cách nào để tạo kiểu hoạt động minh bạch như int nhưng luôn được khởi tạo thành -1?

Tôi muốn biết cả cách thực hiện việc này khi có và không có C++ 11.

+0

Bạn có nghĩ về việc cung cấp một nhà điều hành chuyển đổi? – Zeta

+0

Đó là gì? :) Hãy cho tôi biết thêm. –

+0

Hãy xem câu trả lời của a.lasram. Đó là về cơ bản những gì tôi có ý nghĩa. – Zeta

Trả lời

11
#include <unordered_map> 
#include <iostream> 

using namespace std; 

template<typename T, T default_value> 
class SelfInitializer 
{ 
public: 
    SelfInitializer(T x = default_value) : x(x) {} 
    operator T&() { return x; } 
    operator const T&() const { return x; } 
private: 
    T x; 
}; 

// demo 
int main() 
{ 
    using minus1 = SelfInitializer<int, -1>; 

    unordered_map<int, minus1> m; 

    m[7] = 3; // assignment works 

    minus1 x = 3; 

    int y = x; // conversion to int works 

    int z = int(x); // explicit conversion works 

    cout << m[7] << endl; 
} 
+0

+1 cho giải pháp chung. –

+0

Liệu 'toán tử =' có hữu ích không? 'my_map [7] = 3' sau đó sẽ hoạt động. – Yakk

+0

@Yakk: Nó đã hoạt động do 'toán tử T &', xem demo. –

8

thêm một nhà điều hành chuyển đổi sang int& để struct của bạn minus1 cư xử giống như một int

struct minus1 { 
    int i; 
    minus1() : i(-1) {} 
    operator int&() { return i; } 
}; 
+2

Sexy C++ ma thuật ở đây. Tôi thích nó. –

+2

Có thể bạn sẽ muốn có một hàm tạo chuyển đổi.'minus1 (int n): i (n) {}' [Hoặc kết hợp với hàm tạo mặc định, 'trừ1 (int n = -1): i (n) {}'.] – aschepler

+0

@aschepler Yep, trình biên dịch nói với tôi là nhiều :) –

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