2012-08-11 8 views
6

これは有効なC++ですか(最新の標準を考慮)?私は、Ubuntu 12.04のツリートップclang/libC++にコンパイルエラーが出ています。有効な場合は、エラーメッセージなどでclang-devリストを郵送します。unordered_set <reference_wrapper <Ty>>は有効ですか?

#include <functional> 
#include <unordered_set> 

struct X 
{ 
    int i; 
}; 

void f() 
{ 
    std::unordered_set<std::reference_wrapper<X>> setOfReferencesToX; 

    // Do stuff with setOfReferencesToX 
} 

**私は、質問/回答が最新の標準に特有のものであることを誇りに思っています。 C++コミュニティ全体として、古い標準に特有のものを適格なものから始めてください。新しい基準は、今や約1年は外れています。

+1

終了ノート。 – Griwes

+0

"C++コミュニティ全体として、以前の標準に特化したものを適格なものから開始してください。いいえ。完全なC++ 11サポートを持つコンパイラにアップグレードできないユーザーがいることを考えると、C++ 11のサポートをゆっくりとアップグレードする特定のコンパイラファミリの人気はあまり知られていません。 2つではないにしても少なくとももう1年はC++ 03を意味します。また、GCCもClangもC++ 11への完全な準拠を主張していないことを忘れないでください。未来は現在ではなく、そうであるとふりをすることはそうしないでしょう。 –

答えて

8

この問題は、std::reference_wrapper<T>に固有の問題ではなく、Xそのものに固有の問題です。

std::unordered_setは、std::reference_wrapper<X>のハッシュ関数と等価関数を定義する必要があります。ハッシュファンクタを2番目のテンプレートパラメータとして渡すことができます。

たとえば、これは動作します:

#include <functional> // for std::hash<int> 

struct HashX { 
    size_t operator()(const X& x) const { 
    return std::hash<int>()(x.i);  
    } 
}; 

、その後

std::unordered_set<std::reference_wrapper<X>, HashX> setOfReferencesToX; 

を別のオプションは、std::hash<X>のための専門を作ることです。

namespace std { 
template <> 
struct hash<X> { 
    size_t operator()(const X& x) const { 
    return std::hash<int>()(x.i);  
    } 
}; 
} 

これは、明示的に避けることができます2番目のテンプレート引数:

std::unordered_set<std::reference_wrapper<X>> setOfReferencesToX; 

等価比較については、クラスX用等価演算子を提供することにより、この問題を解決することができます

struct X 
{ 
    bool operator==(const X& rhs) const { return i == rhs.i; } 
    int i; 
}; 

そうしないと、あなたはあなた自身のファンクタを定義し、第三テンプレート引数として渡すことができます。

+0

'std :: hash'を少し特殊化しないでしょうか? – Griwes

+0

'std'名前空間にものを入れたいと思っているのなら、それはそうです。 – juanchopanza

+0

私はそれが単なる特殊化であるので、 "std'の中​​に" put stuff "として認定されるべきではないと思っています。 – Griwes

関連する問題