【问题标题】:constexpr void function rejectedconstexpr void 函数被拒绝
【发布时间】:2015-05-29 10:55:15
【问题描述】:

我有一个非常简单但无法编译的函数。

constexpr void func()
{
}

我得到的错误是:

错误:constexpr 函数“constexpr void func()”的无效返回类型“voidconstexpr void func()

在 C++14 中,void 是文字类型 [§3.9/10]:

一个类型是一个文字类型如果它是:

  • 无效;或
  • 标量类型;或
  • 引用类型;或
  • 文字类型的数组;或
  • 具有以下所有属性的类类型(第 9 条):
    • 它有一个微不足道的析构函数,
    • 它是一种聚合类型 (8.5.1) 或至少有一个 constexpr 构造函数或构造函数模板不是复制或移动构造函数,并且
    • 它的所有非静态数据成员和基类都是非易失性文字类型。

有人可以解释为什么这是无效的吗?

【问题讨论】:

  • Void as a literal type? 的可能重复项
  • 引用 C++14 后的工作草案对于证明有关 C++14 的事实并不是很有用。

标签: c++ language-lawyer c++14 return-type constexpr


【解决方案1】:

使void 成为文字类型的提案是n3652 Relaxing constraints on constexpr functions。 G++ 决定将此功能推送到版本5(我使用的是4.9.2):

G++ 现在支持 C++14 扩展的 constexpr。

constexpr int f (int i)
{
  int j = 0;
  for (; i > 0; --i)
    ++j;
  return j;
}

constexpr int i = f(42); // i is 42

Clang 从 3.4 版开始实现了这一点。

【讨论】:

    【解决方案2】:

    确实有效,但 GCC 尚不支持。标准中的一个示例实际上包括返回 voidconstexpr 函数 - 请参阅 [dcl.constexpr]/1:

    constexpr void square(int &x); // OK: declaration
     // [..]
    constexpr void square(int &x) { // OK: definition
        x *= x;
    }
    

    Example on Coliru 使用 Clang,符合此处。

    【讨论】:

      【解决方案3】:

      取自The C++ Programmig Language (4th Edition)

      constexpr 函数可能没有副作用。

      那么,constexpr void 函数的目的是什么?

      如果你打算做这样的事情:

      constexpr void Twice(int &a)
      {
          a *= 2;
      }
      

      您应该考虑改为:

      constexpr int Twice(int a)
      {
          return 2 * a;
      }
      

      【讨论】:

      • 目的?简单,例如:template constexpr void requireIntegral() { static_assert(std::is_integral::value, "type must be integer"); };
      • 你说得对,好点子。从来没有想过那样使用 constexpr 函数。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-04-21
      • 2014-10-04
      • 1970-01-01
      • 2017-08-08
      • 2012-07-07
      • 2012-07-31
      • 1970-01-01
      相关资源
      最近更新 更多