当前我正在阅读Scott Meyers的Effective Modern C++(项目15 - 尽可能使用constexpr。)。作者说:当编译时不知道参数时,不调用`constexpr`构造函数
当constexpr函数被调用与被 不是在编译期间已知的一个或多个值,它就像一个正常的功能, 计算其在运行时的结果。这意味着您不需要两个函数来执行相同的操作,一个用于编译时间 常量,另一个用于所有其他值。 constexpr函数全部都是 。
我尝试了下面的代码片段在http://coliru.stacked-crooked.com/
#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;
}
在创建p1
对象一切如预期的情况:参数被称为编译时和成员被正确初始化。在创建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编译器。 所以,我不明白是什么问题。也许我错过了什么......
你不应该申报'p2'为'constexpr',因为它不能。所以只要'点p2(a,b);''''' – songyuanyao
为什么?在'p1'中,成员初始化编译时间,因为我们有编译时间的已知参数:2.3,4.4。在'p2'情况下,我们不知道'a'和'b'编译时间的值,并不意味着成员应该已经初始化了运行时? (当一个constexpr函数被调用时,有一个或多个在编译期间未知的值,它就像一个普通函数,在运行时计算其结果。) –
您的报价仅指函数。如果你声明一个对象或表达式'constexpr',你需要在编译时进行评估,而'p2'不能像宋玉瑶指出的那样。 – patatahooligan