2017-05-04 71 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()將其參數的所有權。