目前我正在阅读 Scott Meyers 的 Effective Modern C++(第 15 项 - 尽可能使用 constexpr。)。作者说:
When a constexpr function is called with one or more values that are not known during compilation, it acts like a normal function, computing its result at runtime. This means you don’t need two functions to perform the same operation, one for compile-time constants and one for all other values. The constexpr function does it all.
我在 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 编译器。
所以,我不明白是什么问题。也许我错过了什么......
最佳答案
来自 cppreference (强调我的):
A
constexpr
variable must satisfy the following requirements:
- its type must be a
LiteralType
.- it must be immediately initialized
- the full-expression of its initialization, including all implicit conversions, constructors calls, etc, must be a constant expression
在你的例子中......
constexpr Point p2(a, b);
...a
和 b
不是常量表达式。为了使它们成为常量表达式,需要将get_a
、get_b
、a
和b
标记为constexpr
:
constexpr double get_a() noexcept
{
return 5.5;
}
constexpr double get_b() noexcept
{
return 5.6;
}
constexpr int a = get_a();
constexpr int b = get_b();
constexpr Point p2(a, b);
关于c++ - `constexpr` 参数在编译时未知时不调用构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46618980/