2017-05-04 16 views
0

私はgcc 4.8.4を使用しています。ポインターのrvalue/const値のオーバーロード

次のコードは、ライン22(示される)から、コンパイラエラーで失敗する:タイプの表現からタイプ 'INT * & &' の基準の

無効初期化 'INT * CONST'

square(ptr)への呼び出しが、左辺バージョンsquareを使用していないのはなぜですか?

#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 *&)'が存在することを知らず、代わりに再帰的に自身を呼び出そうとします。 'int * &&'に代入されます。 –

答えて

3

あなたは順序の問題を抱えている:

return square(ptr); 

int square(int* &&num)宣言を参照して

そしてint square(const int* &num)int square(int*const &num)ことsould無効です。

Fixed version

+1

'const int *'と 'int * const'は2つの異なるものです。最初はconstのint型への非constポインタであり、2つ目はconst以外の 'int'へのconstポインタです。 –

+0

ありがとう、それは確かに(ばかげた)間違いでした。 –

1

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()は、その引数の所有権を取得することを非常に明確です。

関連する問題