繁体   English   中英

重载指针的右值/常量左值

[英]Overloading rvalue/const lvalue for pointer

我正在使用gcc 4.8.4。

以下代码由于第22行(​​指示)的编译器错误而失败:

从类型'int * const'的表达式对类型'int * &&'的引用的无效初始化

为什么不使用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的指针,所以lvalue函数仍然不是候选项。

您可以更改它以接受对指向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()将获得其参数的所有权。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM