は現在、私はスコット・マイヤーズ効果的な近代的なC++( - 使用constexprの可能な限り。項目15)を読んでいます。著者は言う:引数がコンパイル時に知られていないとき、 `constexpr`コンストラクタが呼び出されない
constexprの機能が コンパイル時に知られていない、それは は、実行時にその結果を計算し、通常の関数のように作用する1つ以上の値で呼び出された場合。これは、コンパイル時には の定数と他のすべての値に対して1つ、同じ操作を実行するために2つの 関数を必要としないことを意味します。 constexpr関数はそれを allで行います。
は、私はすべてが期待通りに行くp1
オブジェクトを作成する場合は
#include <iostream>
class Point
{
public:
constexpr Point(double a, double b) noexcept
: _a(a), _b(b)
{
}
void print() const noexcept
{
std::cout << "a -> " << _a << "\tb -> " << _b << std::endl;
}
private:
double _a;
double _b;
};
double get_a() noexcept
{
return 5.5;
}
double get_b() noexcept
{
return 5.6;
}
int main()
{
constexpr Point p1(2.3, 4.4);
p1.print();
int a = get_a();
int b = get_b();
constexpr Point p2(a, b);
p2.print();
return 0;
}
http://coliru.stacked-crooked.com/に次のコードスニペットを試してみた:引数はコンパイル時に知られており、メンバーが正しく初期化されています。 p2
オブジェクトを作成する場合、コンパイル時に変数a
とb
の値はわかりませんが、コンストラクタが通常の関数として動作している必要があるため、私の理解のもとになっているはずです。しかし、私は次のエラーメッセージを取得しています:
main.cpp: In function 'int main()'
main.cpp:38:28: error: the value of 'a' is not usable in a constant expression
constexpr Point p2(a, b);
^
main.cpp:36:9: note: 'int a' is not const
int a = get_a();
^
main.cpp:38:28: error: the value of 'b' is not usable in a constant expression
constexpr Point p2(a, b);
^
main.cpp:37:9: note: 'int b' is not const
int b = get_b();
Coliru
はGCCコンパイラを使用しています。 問題は何か分かりません。たぶん私はcppreference(強調鉱山)から何か...
それのであなたは、 'constexpr''としてp2'を宣言するべきではありませんすることはできません。だから、ちょうど 'ポイントp2(a、b);はうまくいくでしょう。 – songyuanyao
なぜですか? 'p1'では、コンパイル時に既知の引数:2.3、4.4があるので、コンパイル時に初期化されます。 'p2'の場合、' a'と 'b'のコンパイル時の値は分かりません。メンバが初期化されているはずです。 (コンパイル時に知られていない値を持つconstexpr関数が呼び出されると、通常の関数のように動作し、実行時に結果が計算されます)。 –
あなたの見積もりは関数を参照します。オブジェクトまたは式 'constexpr'を宣言すると、コンパイル時に評価されることが必要になります。これは、' p2'はソングゥワニが指摘するようにはできません。 – patatahooligan