用于指针的rvalue/const lvalue
Overloading rvalue/const lvalue for pointer
我正在使用GCC 4.8.4。
以下代码失败,第22行的编译器错误(指示(:
从类型的" int* const"
的表达式的类型" int*&&&"引用的初始化无效
为什么不使用square
的LVALUE版本来调用square(ptr)
?
#include <iostream>
#include <memory>
int square(int* &&num) {
std::cout << "rvalue" << std::endl;
std::unique_ptr<int> x(num);
const auto ptr = x.get();
return square(ptr); // this is line 22
}
int square(const int* &num) {
std::cout << "lvalue" << std::endl;
return (*num) * (*num);
}
int main() {
std::unique_ptr<int> up(new int);
*up = 5;
std::cout << square(up.release()) << std::endl;
}
您有订单问题:
return square(ptr);
仅参见int square(int* &&num)
声明,而无效
和 int square(const int* &num)
应该是 int square(int*const &num)
。
固定版本。
在第22行中,范围中 square()
的唯一定义是采用RVALUE参考-int square(int* &&)
的定义。ptr
是一个LVALUE,因此错误消息解释了类型的差异。
如果您交换功能定义的顺序,以便int square(const int* &)
也处于范围中,您仍然会遇到相同的错误。那是因为您有一个指向可变的int
的指针,因此LVALUE功能仍然不是候选者。
您可以将其更改为接受const引用指向INT的指针:
int square(int *const& num) {
std::cout << "lvalue" << std::endl;
return (*num) * (*num);
}
现在该程序编译和运行。
显然,这可以简化以按值接受num
,但我猜您想用比int
更重的东西使这项工作。
重写示例
#include <iostream>
#include <memory>
int square(int *const& num) {
std::cout << "lvalue" << std::endl;
return *num * *num;
}
int square(int*&& num) {
std::cout << "rvalue" << std::endl;
std::unique_ptr<int> x(num);
const auto ptr = x.get();
return square(ptr);
}
int main() {
auto up = std::make_unique<int>(5);
std::cout << square(up.release()) << std::endl;
}
作为附带说明,我尝试避免使用unique_ptr::release()
-与Pre -c 11代码接口时,它可以使用裸指针的所有权,但是在不详细介绍该代码的情况下,很难理解它。现代代码应该更喜欢通过智能指针:
int square(std::unique_ptr<int>&& x) {
std::cout << "rvalue" << std::endl;
const auto ptr = x.get();
return square(ptr);
}
int main() {
auto up = std::make_unique<int>(5);
std::cout << square(std::move(up)) << std::endl;
}
在这里,很清楚square()
将拥有其论点的所有权。