2014-06-17 77 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