`编译时参数未知时,不调用constexpr`构造函数 目前我正在阅读Scott Meyers的有效的现代C++(项目15——尽可能使用CONTXPR)。作者说:
当使用一个或多个 编译过程中不知道,它的作用类似于普通函数, 在运行时计算其结果。这意味着你不需要两个 函数来执行相同的操作,一个用于编译时 常数,一个用于所有其他值。constexpr函数可以实现这一点 全部 我在中尝试了以下代码段`编译时参数未知时,不调用constexpr`构造函数 目前我正在阅读Scott Meyers的有效的现代C++(项目15——尽可能使用CONTXPR)。作者说:,c++,c++11,c++14,C++,C++11,C++14,当使用一个或多个 编译过程中不知道,它的作用类似于普通函数, 在运行时计算其结果。这意味着你不需要两个 函数来执行相同的操作,一个用于编译时 常数,一个用于所有其他值。constexpr函数可以实现这一点 全部 我在中尝试了以下代码段 Coliru使用gcc编译器。 所以,我不明白问题出在哪里。也许我错过了什么…(我的): constepr变量必须满足以下要求: 其类型必须是LiteralType 它必须立即初始化 其初始化的完整表达式,包括所有隐式转换、构造函数调用等,必须是常量表达式 在
Coliru
使用gcc编译器。
所以,我不明白问题出在哪里。也许我错过了什么…(我的):
constepr
变量必须满足以下要求:
- 其类型必须是
LiteralType
- 它必须立即初始化
- 其初始化的完整表达式,包括所有隐式转换、构造函数调用等,必须是常量表达式
constexpr Point p2(a, b);
…a
和b
不是常量表达式。为了使它们成为常量表达式,需要将get_a
、get_b
、a
和b
标记为constepr
:
constexpr double get_a() noexcept
{
return 5.5;
}
constexpr double get_b() noexcept
{
return 5.6;
}
Point p2(a, b); // This works, even though Point(int,int) is constexpr
来自(我的):
constepr
变量必须满足以下要求:
- 其类型必须是
LiteralType
- 它必须立即初始化
- 其初始化的完整表达式,包括所有隐式转换、构造函数调用等,必须是常量表达式
constexpr Point p2(a, b);
…a
和b
不是常量表达式。为了使它们成为常量表达式,需要将get_a
、get_b
、a
和b
标记为constepr
:
constexpr double get_a() noexcept
{
return 5.5;
}
constexpr double get_b() noexcept
{
return 5.6;
}
Point p2(a, b); // This works, even though Point(int,int) is constexpr
您误解了Scott的解释:他并不是说您可以使用非常量数据创建
constexpr
对象。这样的构造不应该起作用
constexpr Point p2(a, b);
因为编译器不知道a
和b
的值,所以不能向编译器声明p2
对象是constepr
他的意思是当你定义一个constexpr
函数或成员函数时,就像这样
int constexpr foo(int a, int b) {
return 2*a + b;
}
当a
和b
是编译时常量时,它显然会工作,但即使a
和b
是变量,它也会继续工作:
cout << foo(2, 5) << endl; // This obviously works
int a, b;
cin >> a >> b;
cout << foo(a, b) << endl; // This works too
您误解了Scott的解释:他并不是说您可以使用非常量数据创建
constexpr
对象。这样的构造不应该起作用
constexpr Point p2(a, b);
因为编译器不知道a
和b
的值,所以不能向编译器声明p2
对象是constepr
他的意思是当你定义一个constexpr
函数或成员函数时,就像这样
int constexpr foo(int a, int b) {
return 2*a + b;
}
当a
和b
是编译时常量时,它显然会工作,但即使a
和b
是变量,它也会继续工作:
cout << foo(2, 5) << endl; // This obviously works
int a, b;
cin >> a >> b;
cout << foo(a, b) << endl; // This works too
您不应该将
p2
声明为constexpr
,因为它不能是。所以只需点p2(a,b)代码>没问题。为什么?在p1
中,case成员在编译时初始化,因为我们有编译时已知的参数:2.3、4.4。在p2
情况下,我们不知道a
和b
编译时的值,这并不意味着成员应该在运行时初始化?(当使用编译期间未知的一个或多个值调用constexpr函数时,它的行为与普通函数类似,在运行时计算其结果。)您的引用仅引用函数。如果你声明一个对象或表达式constexpr
,你需要在编译时对它求值,而p2
不能像宋元耀指出的那样。@DavidHovsepyan是的,它是在运行时求值的,所以它不能是constexpr
,这需要在编译时求值。好的,我知道了。我只是认为编译器会理解构造函数将在运行时被调用,并且在声明p2
之前它将忽略constexpr
关键字。您不应该将p2
声明为constexpr
,因为它不能被调用。所以只需点p2(a,b)代码>没问题。为什么?在p1
中,case成员在编译时初始化,因为我们有编译时已知的参数:2.3、4.4。在p2
情况下,我们不知道a
和b
编译时的值,这并不意味着成员应该在运行时初始化?(当使用编译期间未知的一个或多个值调用constexpr函数时,它的行为与普通函数类似,在运行时计算其结果。)您的引用仅引用函数。如果你声明一个对象或表达式constexpr
,你需要在编译时对它求值,而p2
不能像宋元耀指出的那样。@DavidHovsepyan是的,它是在运行时求值的,所以它不能是constexpr
,这需要在编译时求值。好的,我知道了。我只是认为编译器会理解构造函数将在运行时被调用,并且在声明p2
之前它会忽略constexpr
关键字。在我的例子中a
和b
不是变量?实际上问题是我声明p2
为constepr
@DavidHovsepyan绝对是的。这意味着您可以将它们传递给constexpr
函数,但这并不意味着函数结果将是constexpr