web-dev-qa-db-ja.com

constexpr関数の本体はreturnステートメントではありません

次のプログラムでは、func()に明示的なreturnステートメントを追加しましたが、コンパイラーから次のエラーが発生します。

m.cpp: In function ‘constexpr int func(int)’:
m.cpp:11:1: error: body of constexpr function ‘constexpr int func(int)’ not a return-statement
 }

これはコードです:

#include <iostream>
using namespace std;

constexpr int func (int x);

constexpr int func (int x) 
{
    if (x<0)                
        x = -x;
    return x; // An explicit return statement 
}

int main() 
{
    int ret = func(10);
    cout<<ret<<endl;
    return 0;
}

次のコマンドを使用して、g ++コンパイラでプログラムをコンパイルしました。

g++ -std=c++11 m.cpp

関数にreturnステートメントを追加してから、なぜ上記のエラーが発生したのですか?

8
msc

C++ 11のconstexpr関数は、それよりも制限が厳しくなります。

から cppreference

関数本体は、削除するかデフォルトにするか、次のもののみを含める必要があります。

  • nullステートメント(プレーンセミコロン)
  • static_assert宣言
  • typedefクラスまたは列挙を定義しない宣言およびエイリアス宣言
  • using宣言
  • usingディレクティブ
  • ちょうど1つのreturnステートメント。

したがって、代わりにこれを言うことができます:

constexpr int func (int x) { return x < 0 ? -x : x; }

static_assert(func(42) == 42, "");
static_assert(func(-42) == 42, "");

int main() {}

この制限はC++ 14で解除されたことに注意してください。

15
mpark

C++ 14より前は、constexpr関数の本体はreturnステートメントのみで構成されている必要があります。内部に他のステートメントを含めることはできません。これはC++ 11で機能します。

constexpr int func (int x) 
{
  return x < 0 ? -x : x;
}

C++ 14以降では、他のほとんどのステートメントと同様に、あなたが書いたものは合法です。

出典

16
Thomas