在定义失败之前使用constexpr函数

时间:2015-04-03 15:01:36

标签: c++

我在使用constexpr时遇到了一些麻烦。本书 C ++ Primer 显示了一行代码:

  constexpr int sz = size(); // only size() is a constexpr function
                             // this code is right

然而,本书没有给出一个具体的例子。所以我自己尝试以下代码:

#include <iostream>
constexpr int fun();
int main()
{
    constexpr int f = fun();
    std::cout << f << std::endl;
}
constexpr int fun()
{
    return 3;
}

但我的编译器说fun()未定义。

如果我将constexpr更改为const,则效果很好,如果我在使用前更改了代码以定义constexpr函数:

#include <iostream>
constexpr int fun()
{
    return 3;
}
int main()
{
    constexpr int f = fun();
    std::cout << f << std::endl;
}

它也很好用。有人可以告诉我为什么吗?

2 个答案:

答案 0 :(得分:17)

constexpr函数在首次使用之前不必定义,但在定义之前进行的任何调用的结果都不是常量表达式。

资料来源:C ++标准草案n4296,第5.20节:

  

条件表达式 e核心常量表达式,除非根据抽象机器的规则评估e评估以下表达式之一:

     
      
  • thisconstexpr函数或constexpr构造函数除外,e正在评估;
  •   
  • 为文字类,constexpr函数或简单析构函数的隐式调用调用除constexpr构造函数之外的函数[注意:重载决策应用为   通常 - 结束说明];
  •   
  • 调用未定义的constexpr函数或未定义的constexpr构造函数;
  •   
  • ...
  •   
草案3485(第5.19节)中的

版本:

  

条件表达式核心常量表达式,除非它涉及以下之一作为潜在评估的子表达式,但是逻辑AND,逻辑OR和条件的子表达式不考虑未评估的操作[注意:重载操作符调用函数。 - 结束说明]:

     
      
  • this [注意:在计算常量表达式时,函数调用替换会使用指向类对象的指针替换this成员函数中每次出现的constexpr。 - 结束说明];
  •   
  • 为文字类或constexpr函数调用constexpr构造函数以外的函数[注意:过载分辨率照常应用 - 结束注释];
  •   
  • 调用未定义的constexpr函数或未定义的constexpr构造函数
  •   
  • ...
  •   

由于标准化之前所做的更改,n2235中的示例int x2 = s. t();实际上变为有效。但是,constexpr int x2 = s. t();仍然是错误。

答案 1 :(得分:3)

必须在首次使用之前定义常量表达式函数。请参阅本节paper,4.1节末尾。