2014-01-10 53 views
6

首先,我很抱歉這個問題的模糊標題。我不確定如何總結它。C++模板專精/重載

我想實現的是以下內容,我希望能夠將不同類型的模板非類型參數傳遞給同一個類模板,從而導致不同的實例化。事情是這樣的:

Foo<1>(); 
Foo<'1'>(); // different types of object 

我不認爲這是可能的,所以我不得不做這樣的事情

template <typename T, T Val> 
struct Foo; 

template <int Val> 
struct Foo<int, Val> 
{}; 

template <char Val> 
struct Foo<char, Val> 
{}; 

//... 

Foo<int, 1>(); 
Foo<char, '1'>(); 

這樣Foo可以基於第一模板參數專業化。然而,這使我想在元編程框架中實現的迷你語言的語法複雜化。有沒有什麼技術可以讓我從Foo<'1'>區分Foo<1>?基本上我想要做的就是設置一個編譯時標誌(在一個枚舉中)來指示是否傳遞了一個intchar,但沒有明確指定它們。

編輯 的回答讓我意識到,我的問題暗示,我真的需要(編譯時),這些對象的實例。我不...

假設標準允許我重載一個類模板,使得Foo<1>Foo<'1'>是不同的類型,並且它們的flag字段包含不同的值。這些類型的可再自行傳遞到另一個類模板,它可以檢查他們,做有趣的東西吧,比如:

template <typename FooType> 
struct Bar 
{ 
    typedef typename If < FooType::flag, int, char >::Type Type; 
}; 

這是非常容易的,當你對明確地傳遞類型無關,但這似乎是多餘的...

+1

呵呵,我從來沒有想過這個。 +1 –

+0

我也沒有,直到我需要它;-) – JorenHeit

+0

這看起來像[我的問題](http://stackoverflow.com/q/9400581/212858)更常見的情況下,其答案恐怕waasn't鼓勵 – Useless

回答

2

您可以使用宏:

#define MAKE_FOO(value) \ 
    Foo<decltype(value), value>() 

其實,我認爲你需要在編譯時廣泛使用功能模板make_something。不幸的是,我不知道如何實現它。

+0

我害怕這是唯一的答案。當然,我已經考慮過這個選項,但是宏指令是邪惡的;-)如果沒有人有更好的主意,那麼將標記爲答案。 – JorenHeit

+0

關於相同的方法,但使用默認的模板參數是什麼? '模板'但不知何故我確定這不會編譯:D – Paranaix

+1

@Paranaix它不會工作,因爲默認參數需要從右側填充。 – mpark

0

你可以做這樣的事情:

template <int Val> 
struct Foo<int, Val> 
{ 
    static MyEnum tag = myTag1; 
}; 


template <char Val> 
struct Foo<char, Val> 
{ 
    static MyEnum tag = myTag2; 
}; 
+0

而目的是什麼? – Paranaix

+0

區分Foo <1>來自Foo <'1'>? –

+0

您仍然必須將'int'或'char'傳遞給'Foo',這正是我想要避免的。我希望編譯器能夠推斷出類型,就像函數重載一樣。 Useless的[post](http://stackoverflow.com/q/9400581/212858)大概是一樣的問題,然後得出結論,這是不可能的... – JorenHeit

1

如果您只是需要編譯時可用的值,但實際上並不需要它們作爲類型的一部分(如果您不需要Foo<int, 1>Foo<int, 2>爲不同類型),那麼您可以使用一個constexpr構造函數以及一個constexpr函數在編譯時產生Foo實例。

#define DECLTYPE_AUTO(expr) \ 
    -> decltype(expr) { return expr; } 

template <typename T> 
struct Foo { 

    constexpr Foo(T t) : value(t) {} 

    T value; 

}; // Foo 

template <typename T> 
constexpr auto MakeFoo(T val) 
    DECLTYPE_AUTO(Foo<T>(val)); 

static_assert(MakeFoo(2).value == 2, ""); 
static_assert(MakeFoo('1').value == '1', ""); 

int main() {} 
+0

有趣......但我認爲這對我沒有多大用處。我的過錯完全是因爲在問題中沒有提供足夠的細節。編輯的問題:-) – JorenHeit