2017-05-04 69 views
0

我正在使用gcc 4.8.4。为指针重载rvalue/const左值

下面的代码失败,并从管线22中的编译器错误(指示):

类型的参考无效初始化 '诠释* & &' 从类型的表达式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; 
} 
+2

'square(const int *&)'在'square(int * &&)'之前被声明了吗?如果不是,那么'square(int * &&)'不知道'square(const int *&)'存在,因此试图递归地调用它自己,而不是因为'const int *'可以' t被分配给一个'int * &&'。 –

回答

3

你有秩序的问题:

return square(ptr); 

只看到int square(int* &&num)声明和无效

而且int square(const int* &num)是前人的精力int square(int*const &num)

Fixed version

+1

'const int *'和'int * const'是两个不同的东西。第一个是const const指针,第二个指向非const const指针。 –

+0

谢谢,这确实是(愚蠢的)错误。 –

1

在第22行,范围中square()的唯一定义是需要右值引用的那个 - int square(int* &&)ptr是一个左值,所以错误消息解释了类型的差异。

如果您交换函数定义的顺序,以使int square(const int* &)也在范围内,您仍然会得到相同的错误。那是因为你有一个指向可变的int的指针,所以左值函数仍然不是候选者。

您可以更改接受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() - 与前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()将其参数的所有权。