2014-06-17 50 views
2

我有一個模板類,看起來像這樣內:C++ - 使用帶有枚舉decltype包含一個模板類

template <typename T> 
class Foo { 
public: 
    enum Mode { Mode1, Mode2, Mode3 }; 
    // ... 
}; 

我實例是:

Foo<float> foo; 
// ... 
auto m = Foo<float>::Mode1; 

但在我看來,一個不必要的冗餘以在實例化Foo模板時使用的類型中包含源依賴項。傳統的解決方案將是對整個類型typedef

typedef Foo<float> FooType; 
FooType foo; 
// ... 
auto m = FooType::Mode1; 

但在我看來,編譯器應該能夠推導與實際實例變量的類型。所以這樣的代替:

Foo<float> foo; 
// ... 
typedef decltype(foo) FooType; 
auto m = FooType::Mode1; 

這編譯。令我百思不解的是,爲什麼我不能做的最後一部分作爲一個單一的表達:

auto m = typename decltype(foo)::Mode1; 

這將導致「預期‘(’爲函數樣式轉換或類型建設」的編譯器錯誤

原因爲什麼我要這樣做呢是因爲我的模板參數比T多得多,而頂層typedef可能是最明智的解決方案,我想知道爲什麼我在單行上使用decltype時沒有工作

我使用鏗鏘3.0,我不能使用-std = C++ 11,所以我只使用默認的C++ fe在鏗鏘3.0的氛圍中。不幸的是我不能在這個版本中使用枚舉類。

+0

'decltype' * *是一個C++ 11的功能,所以是用auto'的'。 – ghostofstandardspast

+0

@ghostofstandardspast是的,我可以訪問Clang 3.0中的默認C++功能,其中包括一些C++ 11功能,如'auto'和'decltype'。我只是無法打開'-std = C++ 11',因爲這是一個禁用了此選項的自定義第三方Clang版本。 – meowsqueak

+0

這似乎很混亂。在我看來,它應該默認爲具有編譯器所具有的所有功能的C++ 11,或者默認爲不具有C++ 11功能的舊標準,除非您有選項。 – ghostofstandardspast

回答

0

這適用於我,使用g ++ 4.8.2。

template <typename T> 
class Foo { 
public: 
    enum Mode { Mode1, Mode2, Mode3 }; 
}; 

int main() 
{ 
    Foo<float> foo; 
    auto m = decltype(foo)::Mode1; 
} 

額外的typename是問題所在。

+0

我實際上得到相同的錯誤信息有或沒有'typename',所以我把它留在了,因爲我不知道是否有必要。 – meowsqueak

+0

我不得不使用'-std = C++ 11'標誌來工作。 –

0

您使用的是decltype,它的功能是introduced in C++11,因此無法在C++ 03中使用它。

幸運decltype一直introduced in Clang 2.9(就像auto),並可通過使用-std=c++11-std=c++0x

你的代碼編譯就好使用C++ 11:

template <typename T> 
class Foo { 
public: 
    enum Mode { Mode1, Mode2, Mode3 }; 
    // ... 
}; 


int main() { 
    Foo<float> foo; 
    // ... 
    auto m = decltype(foo)::Mode1; 
} 

Live demo

+0

C++ 03是鏗鏘3.0的默認方言嗎? – meowsqueak

+0

那麼這個問題可能會部分支持'decltype'呢?鑑於該關鍵字是可識別的並且在兩行版本中起作用,所以它在單行版本中的使用完全不受支持 - 可能錯誤地認爲'decltype'「返回」此版本的類型編譯器(否則'decltype(foo):: Mode1'會工作)? – meowsqueak