我有以下代码
constexpr int into(int a,int b)
{
int c=a*b;
return c;
}
int main()
{
constexpr int &n=into(5,5);
}
我已阅读(在MSDN中)
关键字
constexpr
是在C ++ 11中引入的,并在C ++ 14中进行了改进。这意味着不断表达。与const
类似,它可以应用于变量,以便在任何代码尝试修改值时引发编译器错误。
在我阅读之后,我认为可以使用constexpr
代替const
,但对于上面的代码,我收到编译错误说明
`int main()': invalid initialization of non-const reference of type 'int&' from an rvalue of type 'int'`
当constexpr
替换为const
时,它可以正常工作。我不明白这种行为;有人可以解释一下吗?
答案 0 :(得分:6)
与适用于const
的{{1}}不同,int
关键字将const直接应用于引用类型constexpr
的变量,该变量无效。
int&
typedef int &int_ref;
int main() {
int x = 1;
int &a = x; // OK
int_ref b = x; // OK, int_ref is 'int &'
const int &c = 1; // OK, reference to const int
const int_ref d = 1; // error: type of d is 'int &'
// qualifier on reference are being ignored
}
和constexpr int &n
是一样的,
虽然constexpr int_ref n
和const int &n
的限定符不同。
答案 1 :(得分:3)
标记为constexpr
的表达式将在编译时解析,这会将into(5,5)
的结果视为int
字面值。我们知道,引用不能绑定到C ++中的int
字面值。
您可以让constexpr int x=into(5,5);
出现在全局范围内并在主要范围内创建constexpr const int
对x
的引用,以强制x
在{{{{}}之前得到解决调用1}}然后允许引用绑定到main
:
x
要专门回答你的问题,这与rvalues或移动语义完全正交,而是constexpr int into(int a,int b) {
int c=a*b;
return c;
}
// guaranteed to be resolved before main is called
constexpr int x = into(5,5);
int main() {
constexpr const int& n = x;
static_assert(n == 25, "whoops!");
}
的细微差别。
如果全局范围给你带来胃灼热,你可以使constexpr
成为x
并在其引用绑定之前进行初始化,这对我来说更自然:
static