为啥右值不能分配给 constexpr 引用变量
Posted
技术标签:
【中文标题】为啥右值不能分配给 constexpr 引用变量【英文标题】:why rvalue can't assign to constexpr reference variable为什么右值不能分配给 constexpr 引用变量 【发布时间】:2016-05-03 12:00:31 【问题描述】:我有以下代码
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
时,它可以正常工作。我不明白这种行为;有人能解释一下吗?
【问题讨论】:
constexpr
引用必须绑定到全局变量。见答案here。
@flatmouse,感谢重播...链接中的答案之一是“引用在概念上等同于获取变量的地址,而局部变量的地址不是常量”在这里当我使用 const 它绑定。但不仅对于 constexpr。我相信 const 和 constexpr 对变量的行为是相同的
问题可能是into
的返回值没有保存在任何地方,但是您确实保存了对该返回值的引用,那么该引用必须指向哪里?
需要保存吗?函数调用是否暂时不将结果保存在任何地方,编译器 RVO 是否起作用?
【参考方案1】:
与const
应用于int
不同,constexpr
关键字将 const 直接应用于引用类型为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
和const int_ref n
的限定符不同。
【讨论】:
【参考方案2】:标记为constexpr
的表达式将在编译时解析,这会将into(5,5)
的结果视为int
文字。众所周知,引用不能绑定到 C++ 中的 int
文字。
您可以通过使constexpr int x=into(5,5);
出现在全局范围内并在主范围内创建constexpr const int
引用来完成这项工作绑定x
:
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
并将其初始化放在其引用绑定之前,这对我来说似乎更自然:
constexpr int into(int a,int b)
int c=a*b;
return c;
int main()
// guaranteed to be resolved before main is called
static constexpr int x = into(5,5);
constexpr const int& n = x;
static_assert(n == 25, "whoops!");
【讨论】:
"我们知道,引用不能绑定到 C++ 中的 int 字面量。",你的意思是什么引用? @erip,不清楚你说的 'into(5,5) 作为 int 文字。正如我们所知,引用不能绑定到 C++ 中的 int 文字。我相信调用 into() 函数返回 int&& 这是一个右值,它应该分配给常量引用,当我把 const int &n=into(5,5); main..if const can 为什么 constexpr 不能是 constexpr 缺少一些东西来处理这种情况 @PiotrSkotnicki 我的意思是对int
文字的引用。 :) int& x = 25;
不合法。您当然可以将 const
引用到 int
文字,但这与我理解的 constexpr
的分辨率不同。
@erip 那么根据你的推理应该可以写成constexpr const int&
@RichardGeorge 澄清:您认为const
和constexpr
相同是错误的。 constexpr
表示“在编译时已知”,const
表示“在每次迭代分配后无法更改”。 const int i& = n;
将 i 分配给本轮的任何 n,但我们不能通过 i 进行修改。 constexpr i = 25
表示 i
在编译期间可以省略并替换为 25。以上是关于为啥右值不能分配给 constexpr 引用变量的主要内容,如果未能解决你的问题,请参考以下文章