可以重新定义constexpr和内联函数吗?

时间:2014-07-12 19:57:50

标签: c++ function inline constexpr

我正在验证关于C ++ Primer的声明:

  

Unlinke其他函数,inline和constexpr函数可以在程序中多次定义。

我在下面使用了一个constexpr cfunc()的两个定义,期望foo_0()将调用第一个def而foo_1()将调用第二个def。但是,尝试失败并出现编译错误(最后)。为什么呢?

constexpr int cfunc(){
  return 42;
}

int foo_0(){
  return cfunc();
}

constexpr int cfunc(){
  return 42;
}

int foo_1(){
  return cfunc();
}


int main(int argc, char **argv) {

  cout << foo_0() << endl;  
  cout << foo_1() << endl;  

  /* testconstexprfunc2.cpp:24:15: error: redefinition of ‘constexpr int cfunc()’ */
  /* testconstexprfunc2.cpp:16:15: error: ‘constexpr int cfunc()’ previously defined here */

  return 0;

}

3 个答案:

答案 0 :(得分:9)

是的,与其他功能不同,内联和constexpr功能可以在程序中多次定义。 但是,定义必须完全匹配。

根据标准的理由:

来自§7.1.5/ 2 constexpr规范[dcl.constexpr]:

  

constexpr函数和constexpr构造函数隐式inline

来自§3.2/ 6一个定义规则[basic.def.odr]:

  

在一个程序中,每个定义都可以有多个类类型(第9条),枚举类型(7.2),inline函数与外部链接...的定义   出现在一个不同的翻译单元......

来自§7.1.2/ 4功能指标[dcl.fct.spec]:

  

inline函数应在每个使用过的翻译单元中定义,并且在每种情况下都应具有完全相同的定义。

因此,由于constexpr函数隐式inline,因此它具有inline函数的所有属性。因此, constexpr函数可以有多个定义,前提是每个定义出现在不同的翻译单元

为什么你的程序失败了:

在您的情况下,程序失败,因为您违反了此规则。也就是说,您在同一个翻译单元(即main.cpp)中重新定义了相同的constexpr函数。

答案 1 :(得分:4)

内联函数可以在程序中多次定义,但在翻译单元中只能定义一次。这意味着它只能在头文件中定义一次。即使翻译单元相同,您也无法在翻译单元中定义多个定义。

答案 2 :(得分:2)

确实如此 - 关于内联函数。这是允许在头文件中使用内联函数的情况,以便在编译时(而不是在链接时)进行内联。

以下引文根本没有提到constexpr,但如上所述,它们是隐式内联的。

正如@R Sahu所解释的那样,关键是provided that each definition appears in a different translation unit,而这里并非如此。

引用标准,§3.2.6:

  

如果每个定义出现在一个不同的翻译单元中,那么(...)内联函数的定义可能不止一个与外部链接(7.1.2)(...)的内联函数,并且定义满足以下要求。 (...)