【问题标题】:A constexpr function is not required to return a constant expression?constexpr 函数不需要返回常量表达式吗?
【发布时间】:2015-07-06 20:43:55
【问题描述】:

C++ Primer(第 5 版)第 240 页有一条注释说明:

constexpr 函数不需要返回常量表达式”。

有人问过这个问题:can constexpr function return type be a non const?。该问题的作者误解了该说明。

但是对它的正确理解是什么(引用帖子的答案澄清了该帖子作者的困惑,但不回答我的问题)?

【问题讨论】:

  • 感谢 Simon 将问题格式化得这么好。我从中学到了新东西。
  • Scott Meyers 在他的新书 Effective Modern C++ 中很好地解释了这个主题
  • @Alejandro 货号是多少?
  • 15 对我来说,在“转向现代 C++”下
  • 下面你有两个很好的答案,他们能回答你的问题吗?

标签: c++ c++11


【解决方案1】:

constexpr 函数必须返回* 必须有一个返回常量表达式的路径,前提是所有参数都是常量表达式。这实际上是有道理的。示例:

constexpr int square(int i){
    return i*i;
}

std::array<int, square(2)> ia; //works as intended, constant expression
int i;
std::cin >> i;
int j = square(i); //works even though i is not a constant expression
std::array<int, square(i)> ia; //fails, because square does not (and cannot)
                               //return a constant expression

*chris更正。

【讨论】:

  • 我不同意。只要函数可以返回一个常量表达式,就可以了。允许接受一个常量表达式参数并返回一个非常量表达式,只要它再次返回一个常量表达式(例如,coliru.stacked-crooked.com/a/a0d9dcadc756749c)。此论点取自 OP 链接到的问题。
  • 在 constexpr 函数中,参数不被视为常量表达式。因此,即使constexpr int foo(int i) { return i; } 也不会返回常量表达式。恕我直言,C++ Primer 中的措辞有点愚蠢。标准要求的是必须能够在常量表达式中调用 constexpr 函数(存在参数以便可以在常量表达式中调用该函数)。
【解决方案2】:

一个(非模板)constexpr函数必须至少有一个返回常量表达式的执行路径;形式上,必须存在这样的参数值,以便 “函数的调用 [...] 可以是核心常量表达式的求值子表达式” ([dcl.constexpr]>5)。例如(同上):

constexpr int f(bool b) { return b ? throw 0 : 0; }     // OK
constexpr int f() { return f(true); }     // ill-formed, no diagnostic required

这里int f(bool) 允许为constexpr,因为它使用参数值false 调用会返回一个常量表达式。

如果 constexpr 函数是一个函数模板的特化,它可能具有至少一个返回常量表达式的特化,则它可能永远不会返回一个常量表达式。再说一遍:

template<bool B> constexpr int g() { return f(B); }    // OK
constexpr int h() { return g<true>(); }    // ill-formed, no diagnostic required

【讨论】:

  • g&lt;true&gt;() 声明为constexpr 有什么用处?你能写constexpr int a = g&lt;true&gt;();吗?我猜不是,因为编译器将无法在编译时计算 a 的初始化值...
  • @MeirGoldenberg 正确,但您可以写成 constexpr int a = g&lt;false&gt;();,因此标准允许 g()constexpr
  • 啊,对了,如果我在专业化中省略constexpr,它将无法编译!谢谢!
  • 您的意思是显式实例化g&lt;true&gt;() 还是显式特化?为什么h() 不正确的 NDR 究竟是什么?
  • @T.C.这是一个显式实例化(不是constexpr-valid 的显式特化是第 6 段中格式错误的 NDR)。很抱歉对 h() 造成任何混淆 - 我忘记了 constexpr 说明符。如您所见,如果没有constexpr,它将是格式良好的。
猜你喜欢
  • 2016-07-29
  • 1970-01-01
  • 1970-01-01
  • 2018-01-08
  • 1970-01-01
  • 2021-12-05
  • 1970-01-01
  • 1970-01-01
  • 2011-07-08
相关资源
最近更新 更多