15

次のプログラムを検討してください。

#include <iostream>
#include <iterator>
#include <vector>
#include <utility>
using namespace std; //just for convenience, illustration only

typedef pair<int, int> point; //this is my specialization of pair. I call it point

istream& operator >> (istream & in, point & p)
{
    return in >> p.first >> p.second;
}

int main()
{
    vector<point> v((istream_iterator<point>(cin)), istream_iterator<point>()); 
    //             ^^^                         ^^^        
    //extra parentheses lest this should be mistaken for a function declaration
}

ADLが名前空間stdで演算子>>を検出するとすぐに、stdで検出された演算子が実行可能な候補であったかどうかに関係なく、グローバルスコープを考慮しなくなるため、これはコンパイルに失敗します。これはかなり不便です。演算子>>の宣言を名前空間std(技術的に違法)に配置すると、コードは期待どおりにコンパイルされます。pointstd名前空間のテンプレートの特殊化としてタイプ定義するのではなく、独自のクラスを作成する以外に、この問題を解決する方法はありますか?

前もって感謝します

4

1 に答える 1

11

operator>>inのオーバーロードを追加するnamespace stdことは禁止されていますが、テンプレートの特殊化を追加することが許可される場合があります。

ただし、ここにはユーザー定義の型はなく、標準型の演算子を再定義する必要はありません。専門化operator>>(istream&, pair<mytype, int>)するのは合理的でしょう。


セクション[namespace.std](n3290のセクション17.6.4.2.1)は言う

特に指定がない限り、名前空間stdまたは名前空間内の名前空間に宣言または定義を追加する場合、C++プログラムの動作は未定義です。プログラムは、宣言がユーザー定義型に依存し、特殊化が元のテンプレートの標準ライブラリ要件を満たし、明示的に禁止されていない場合にのみ、任意の標準ライブラリテンプレートのテンプレート特殊化を名前空間に追加できます。stdstd

(強調鉱山)

于 2011-07-30T18:25:52.393 に答える