2015-03-24 19 views
0

我有color類模板,一些typedef S於它,和一堆顏色常量:如何只允許來自預定義的一組常量的值?

template<typename T> 
class color 
{ 
public: 
    color(T data) : data(data) {} 
    // other functions... 
private: 
    T data; 
}; 
typedef color<uint16_t> color16; 
typedef color<uint32_t> color32; 

typedef color16 guicolor; 
const guicolor WHITE = 0xFFFF; 
const guicolor BLACK = 0x000F; 
// other colors... 

我也有一些功能,這採取預定義的guicolor常量之一,例如:

void foo(guicolor Color) { ... } 

然而,foo還接受color<uint16_t>類不僅僅是預定義的常量guicolor,這是不希望BEC的其他實例因爲您應該只能使用GUI使用的預定義顏色集合。

我能guicolorcolor16一個子類,但它是值得的/好的做法,因爲我不會添加任何附加功能的那類,只是把它作爲一個名稱從其他color16實例來區分?還有其他解決方案嗎?

+2

如果您要求解決問題而不是專門學習問題的答案,您應該詳細說明您的約束;不明白爲什麼其他實例不受歡迎,也不明白爲什麼你不使用'enum'。 – Hurkyl 2015-03-24 23:49:35

+0

@Hurkyl我沒有使用'enum',因爲你不能擁有一個類類型的'enum'。任何想法我應該補充什麼?我想我已經在問題中包含了所有的限制。 – emlai 2015-03-24 23:52:12

+0

我認爲最好的選擇是製作一個'predefined_color'子類。我想不出任何其他更清晰的想法。除了改變功能採取任何顏色的對象。其實,是的...做那個。 – 2015-03-24 23:54:00

回答

1

雖然評論中的建議可能是一些可能的選擇,但我知道另一個竅門。

而不是定義guicolortypedef或子類,我們可以定義它爲一個分離的類,與3個技巧。

class guicolor 
{ 
private: 
    uint16_t data; 

private: // Trick 1: private constructor! 
    guicolor(uint16_t data) : data(data) {} 

public:  // Trick 2: custom conversion! 
    operator color16() const 
    { 
     return color16(this->data); 
    } 

public:  // Trick 3: static members! 
    static const guicolor White; 
    static const guicolor Black; 
}; 

// Static members need to be *declared* in the class, and *defined* outside. 
const guicolor guicolor::White = 0xFFFF; 
const guicolor guicolor::Black = 0x0000; 

然後,foo函數就是你寫的。

void foo(guicolor c) { ... } 

接下來是用法。

color16 some_color_1 = 0xF000; // Normal 
color16 some_color_2 = guicolor::White; // guicolor object is implicitly convertible to color16 

guicolor some_guicolor_1 = 0x1234; // Compilation error as expected, due to private constructor. 
guicolor some_guicolor_2 = guicolor::White; // Compilation pass, due to the pre-defined static member and compiler generated public copy constructor. 

foo(some_color_1);  // Compilation error as expected 
foo(some_guicolor_2); // Compilation pass 
+0

私有構造函數+類內靜態實例化,不錯的技巧!謝謝,有一天可能會派上用場。 – emlai 2015-03-25 02:22:11