用于指针的rvalue/const lvalue

Overloading rvalue/const lvalue for pointer

本文关键字:const lvalue rvalue 指针 用于      更新时间:2023-10-16

我正在使用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()将拥有其论点的所有权。