为指针重载 rvalue/const 左值
Overloading rvalue/const lvalue for pointer
我正在使用 gcc 4.8.4。
以下代码因第 22 行(指示)中的编译器错误而失败:
invalid initialization of reference of type ‘int*&&’ from expression of type ‘int* const’
为什么不使用 square
的左值版本调用 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()
的唯一定义是采用右值引用的定义 - int square(int* &&)
。 ptr
是左值,因此错误消息解释了类型的差异。
如果交换函数定义的顺序,使 int square(const int* &)
也在范围内,您仍然会遇到相同的错误。那是因为你有一个指向可变 int
的指针,所以左值函数仍然不是候选者。
您可以将其更改为接受对指向 int 的指针的 const 引用:
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()
- 在与获取裸指针所有权的 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()
将取得其论点的所有权。
我正在使用 gcc 4.8.4。
以下代码因第 22 行(指示)中的编译器错误而失败:
invalid initialization of reference of type ‘int*&&’ from expression of type ‘int* const’
为什么不使用 square
的左值版本调用 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()
的唯一定义是采用右值引用的定义 - int square(int* &&)
。 ptr
是左值,因此错误消息解释了类型的差异。
如果交换函数定义的顺序,使 int square(const int* &)
也在范围内,您仍然会遇到相同的错误。那是因为你有一个指向可变 int
的指针,所以左值函数仍然不是候选者。
您可以将其更改为接受对指向 int 的指针的 const 引用:
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()
- 在与获取裸指针所有权的 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()
将取得其论点的所有权。