【问题标题】:can have definition variable of non-literal type in constexpr function body c++14?在 constexpr 函数体 c++14 中可以有非文字类型的定义变量吗?
【发布时间】:2014-03-14 07:03:17
【问题描述】:

我认为在 C++14 中,从 constexpr 中删除了更多限制。但根据 N3797 7.1.5 3-punct:


conexpr 函数的定义应满足以下约束:

  • 它不能是虚拟的
  • 它的返回类型应该是文字类型;
  • 它的每个参数类型都应该是文字类型;
  • 它的 function-body 应该是 = delete、= default 或一个 compound-statement不包含:
  • asm 定义
  • goto 语句,
  • 一个try-block,或者
  • 非文字类型或静态或线程存储持续时间的变量的定义,或者没有初始化的变量的定义 执行。

我知道为什么不允许使用静态、线程存储持续时间变量,但我看不出任何原因,为什么只允许定义文字类型的变量?

或者我不理解标准。

我不确定,但根据标准,即使 C++14 也应该创建以下错误:

struct point{
constexpr point(): x(0), y(0){}
constexpr point(int x_, int y_): x(x_),y(y_){}
constexpr int hypot()const { return x*x + y*y; }
int x,y;
};

constexpr int hypot(int x, int y) {  
   point p{x,y}; //error, because p - is not literal type.
   return p.hypot();
}

// error, because return type is not literal.
constexpr point  getPoint(int x, int y) { return {x,y}; }

// error, because parameter is not literal.
constexpr int hypot(point p) { return p.hypot(); }

问:如果真的会发生上述错误,为什么不取消这些限制?

【问题讨论】:

    标签: c++ c++11 language-lawyer constexpr c++14


    【解决方案1】:

    文字类型在 3.9/10 中定义:

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

    • void;或

    • 标量类型;或

    • 引用类型;或

    • 文字类型的数组;或

    • 具有以下所有属性的类类型(第 9 条):

      • 它有一个微不足道的析构函数,

      • 它是一种聚合类型 (8.5.1) 或至少有一个 constexpr 构造函数或构造函数模板不是复制或移动构造函数,并且

      • 它的所有非静态数据成员和基类都是非易失性文字类型

    所以你的结构point 一个文字类型,你的示例代码是有效的 C++1y。

    至于为什么constexpr 函数仅限于文字类型的变量,它们是唯一保证在编译时可解释的类型。

    【讨论】:

    • 谢谢,我认为文字类型只有整数、字符、字符串文字和浮点文字。我修复了 getPoint。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-16
    • 2011-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-25
    相关资源
    最近更新 更多