9

私は次のようなconstexpr関数を持っています:

constexpr int foo(int bar)
{
   static_assert(bar>arbitrary_number, "Use a lower number please");

   return something_const;
}

しかし、これをGCC 4.6.3でコンパイルすると、私に言われ続けます

エラー:「バー」は定数式に表示できません

私は次のようなことを試みました

constexpr int foo(constexpr const int bar)
{
   static_assert(bar>arbitrary_number, "Use a lower number please");

   return something_const;
}

ただし、constexprは関数の引数には使用できません。

バーが常にコンパイル時定数であることをコンパイラに伝える簡単な方法はありますか?

4

3 に答える 3

17

バーが常にコンパイル時定数であることをコンパイラに伝える簡単な方法はありますか?

barが常にコンパイル時定数である場合は、関数を次のように記述する必要があります。

template<int bar>
constexpr int foo()
{
   static_assert(bar>arbitrary_number, "Use a lower number please");
   return something_const;
}

そうしないで、代わりにすでに書いたものを書く場合、その場合、関数はnon-const引数を使用して呼び出すこともできます。非const引数を渡すと、関数はそのconstexpr-nessを失います。

上記のコードarbitrary_numberでも定数式である必要があることに注意してください。そうでない場合、コンパイルされません。

于 2012-03-20T15:43:06.503 に答える
5

constexpr関数constexprコンパイル時に評価される場合がありますが、一般に標準では強制されません(変数を初期化するなど、定数式内で関数を使用することにより、コンパイル時に関数を強制的に評価できます)。

また、constexpr関数の引数は実際には定数ではなく、呼び出しごとに変更される可能性があります(コンパイル時に評価された場合でも)。

回避策の1つは、型以外のテンプレートを使用して渡すbarことです。これが常にコンパイル時定数である場合(そう思われます)。

于 2012-03-20T15:44:45.500 に答える
0

foo次のように使用できます。

int i;
std::cin >> i;
foo("foo", i);

ご覧iのとおり、上記の定数式ではありませんが、constexpr関数で使用できます。関数(および関数テンプレート)は、たとえば定数式iffであり、通常の関数のよう使用できることconstexprを保証する奇妙な獣です。foo(p, i)pi

関数の引数が本当に常に定数式であることが意図されている場合、それらは関数の引数ではなく、テンプレートの引数である必要があります。

于 2012-03-20T15:44:29.337 に答える