2017-06-28 2 views
0

私はconstexprを学習していますが、constexprは実行時間ではなくコンパイル時に関数を計算するようコンパイラに指示します。私はテストのために次のコードを使用しましたが、私は本当に理解していないエラーにぶつかりました。なぜ説明できますか?コンパイルエラー:constexprを使用してstd :: arrayのサイズを宣言します

#include <iostream> 
#include <array> 
using namespace std; 

constexpr int foo(int i) 
{ 
    return i + 5; 
} 

int main() 
{ 
    int i = 10; 
    std::array<int, foo(5)> arr; // OK 
    // But... 
    std::array<int, foo(i)> arr1; // Error 
} 

エラーがある:「i」の値は、定数式に使用できません。どうして? iは事前に宣言されていますが、なぜそれがconstである必要がありますか?

答えて

5

for my understanding constexpr tells the compiler to calculate functions during compile time instead of running time.

正確には:constexprで、コンパイラは関数コンパイル時間を計算できません。そしてコンパイラは必要かつ可能なときにそれを行います。 (5がコンパイル時に知られているので)

std::array<int, foo(5)> arr; // OK 

の場合には(std::arrayの第2のテンプレート引数がコンパイル時に知られなければならないので)必要だと可能。

しかし

int i = 10; 
std::array<int, foo(i)> arr1; // Error 

でそれが必要(std::array)しかし、ことはできません(iは、一定ではなく可変であり、コンパイラはコンパイル時間をi値を使用するだけの時間を実行することはできませんので)。

これは必須ではありませんので、エラーです。

しかし、それは可能コールfoo(i)コンパイル時ではないのですが、それは必要ありませんので、あなたが

int i { 10 }; 
int j { foo(i) }; 

を書くことができます(jは、実行時に初期化することができるため)。だからfoo(i)は、(おそらくは)ランタイムと呼ばれます。

foo(i)を使用してstd::arrayをコンパイルするには、あなたがconstexpr(またはconst)などiを定義する必要が

constexpr int i { 10 }; 

ので、コンパイラはiコンパイル時の値を使用することができます。

Why? i is declared beforehand why does it have to be a const?

短い答え:C++ 11の標準ではそうだと言えます。

長い答え:このように、コンパイラを構築する方が簡単です。値のコンパイル時に使用する場合は、それをconstexprと宣言し、コンパイラが変更されていないことをチェックします。それは(比較的)簡単です。

そうでなければ、定数ではない変数の値をコンパイル時に使用できる場合、コンパイラはconstexpr関数で使用されたときにその値を決定する変数の話に従うべきです。あなたのおもちゃの例では、シンプルで、実際の生活では悪夢になるでしょう。

関連する問題