2017-10-23 10 views
2

は、セクション13.3:スワップ内部の使用宣言はの宣言を隠していない理由はC++入門第5回で

非常に慎重な読者は不思議に思うかもしれませんスワップのバージョンHasPtr(6.4.1)。このコードが18.2.3で動作する理由を説明します。ここで

サンプルコードです:

確か
void swap(HasPtr &lhs, HasPtr &rhs) 
{...} 

void swap(Foo &lhs, Foo &rhs) 
{ 
    using std::swap; 
    swap(lhs.h, rhs.h); 
} 

using std::swapvoid swap(Foo &lhs, Foo &rhs)の範囲内void swap(HasPtr &lhs, HasPtr &rhs)を隠しません。なぜ、私は疑問に思って?代わりに、std::swap関数とvoid swap(HasPtr &lhs, HasPtr &rhs)がオーバーロードされているようです。

これは(C++プライマー第五、6.4.1項より引用)次の文に反している:

我々は内側のスコープ内の名前を宣言した場合は、その名前がで宣言されたその名前の使用を隠します外側の範囲。名前はスコープを超えてオーバーロードされません。

は、私たちは、次の例について考えてみましょう:この場合

#include<iostream> 
namespace a{ 
    void f(int a){ std::cout<< "a::f(int)";} 
} 
void f(double a){ std::cout<< "f(double)";} 

int main(){ 
    using a::f; 
    f(1.11); 
} 

を我々はusing a::fを使用する場合、それは外側のスコープで機能void f(double a)を隠します。したがって、我々はvoid f(double a)が良く一致してきたでしょう(しかし、それが隠されている)が、機能void f(int a)は、ここで使用されていることを意味し、次の出力

a::f(int) 

を取得します。締結する

、それは

第二の場合に外側のスコープで最初のケースで外側のスコープ内のすべての swap機能 (2) using a::f 全て f機能 (1) using std::swap 過負荷と思わ

私の質問は、そのような違いはなぜですか?

ところで、これはFunction hiding and using-declaration in C++に関連していますが、その中のすべての答えは、すべてのスワップ機能が理由を説明せずに過負荷であると主張しているため、ここで別の質問を開きます。

+0

書籍の18.2.3項を読んでみませんか? – Justin

+2

私は正しい動作を100%確信しているわけではありませんが、私が正しいとすれば、 'std :: swap'を使うと他の機能を隠してしまいます。しかし、優先順位を持つArgument Dependent Lookup(ADL)というものがあります。基本的に、 'swap(lhs.h、rhs.h)'を書くと、コンパイラはまずADLの規則に従って関数swapを探します(基本的に、関数の型が定義されている名前空間を見てください)。 'swap'という名前を引数の1つとしてタイプする)、そのような' swap'を見つけることができなければ、コールサイトで 'swap'関数を呼び出します。これは' std :: swap'です。 'std :: swap'を使用しています – Justin

+0

:: f(int)名前を探す場所を尋ねています –

答えて

1

あなたは

using a::f; 

を使用するときは、宣言型の地域の範囲にa::fの宣言をもたらしています。ここでは宣言的領域部分が重要です。

あなたの場合、宣言的な領域はmainです。 mainにはfという他の宣言はありません。したがって、fa::fに解決されます。a::fとグローバルf両方がメイン、使用から見ることができるようにする

using a::f; 
void f(double a){ std::cout<< "f(double)";} 

あなたがそれを行う場合は、a::fとグローバルf両方がmainに利用可能になります。

https://ideone.com/ySvGlPで作業してください。