【问题标题】:C++ - using decltype with enum contained within a templated classC++ - 使用 decltype 和包含在模板类中的枚举
【发布时间】:2014-06-17 01:01:13
【问题描述】:

我有一个看起来像这样的模板类:

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;

这会导致编译器错误“Expected '(' for function-style cast or type construction”。

我之所以要这样做,是因为我有比T 更多的模板参数,虽然顶级 typedef 可能是最明智的解决方案,但我想知道为什么我使用 decltype单行不行。

我使用的是 Clang 3.0,但无法使用 -std=c++11,因此我只能使用 Clang 3.0 中的默认 C++ 功能。不幸的是,我不能在这个版本中使用枚举类。

【问题讨论】:

  • decltype C++11 特性,auto 的使用也是如此。
  • @ghostofstandardspast 是的,我可以访问 Clang 3.0 中的默认 C++ 功能,其中包括一些 C++11 功能,例如 autodecltype。我只是无法打开 -std=c++11,因为这是一个自定义的第三方 Clang 版本,已禁用此选项。
  • 这看起来很混乱。在我看来,它应该默认为具有编译器所有功能的 C++11,或者默认为没有 C++11 功能的旧标准,除非您有选择权。

标签: c++ enums typedef decltype


【解决方案1】:

这对我有用,使用 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 是问题所在。

【讨论】:

  • 不管有没有typename,我实际上都会收到相同的错误消息,所以我把它留在了,因为我不确定它是否有必要。
【解决方案2】:

你正在使用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

【讨论】:

  • C++03 是 Clang 3.0 的默认方言吗?
  • 那么问题可能是对decltype的部分支持呢?鉴于该关键字已被识别并且在两行版本中有效,因此它在单行版本中的使用完全不受支持是合理的 - 假设 decltype 在此版本中“返回”一个类型可能是错误的编译器(否则 decltype(foo)::Mode1 会工作)?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多