3

hash<>私が取り組んできた型のファミリーに特化したものを提供しようとしています。これまでのところ、専門化自体は簡単に提供できます。私はすでに同様のことを行っていnumeric_limits<>ます。しかし、C++11 および -pre-11 (C++03 など) に移植可能な方法で特殊化を提供する方法の問題に直面しています。

もちろん、私がぶつかっている問題はhash<>、いくつかの名前空間の 1 つで定義できることであり、同じ名前空間で特殊化を提供することを余儀なくされています。

// in c++11
namespace std { struct hash<>...; }
// in c++03 this is one possibility
namespace std { namespace tr1 { struct hash<>...; } }

// my library's specialization
namespace ????_open {
struct hash<mytype>...;
????_close

もちろん、#defines を使用して適切な名前空間に到達し、開いて閉じるか、N 個のファイルに N 個の異なる特殊化を提供し、条件付きで正しいものを #include することもできますが、これは面倒です。

#if defined(some_c++11_condition)
  #include "c++11-specialization.h"
#elif defined(some_c++03_condition)
  #include "c++03-specialization.h"
#elif (some_other_condition)
  #oh_dear_who_knows_what_this_include_will_be_like
#else_ad_nauseam
#endif

もちろん、やむを得ない場合はその戦略に固執しますが、以前にいくつかの他のオプションを検討したかった. 特に、名前空間エイリアスを使用して正しい場所に特化できると思いました。

#if defined(some_c++11_condition)
  namespace std_specialize = std;
#elif defined(some_c++03_condition)
  namespace std_specialize = std::tr1;
#...
#endif

...

namespace std_specialize {
struct hash<mytype>...;
}

残念ながら、これは私が試した 3 つのコンパイラ (MSVC 2008、GCC 4.7、Clang 3.0) のいずれでも機能せずdeclaration of namespace conflicts with...、名前空間を再度開く行の " " に関するさまざまなエラーが発生します。エイリアスがエイリアスであり、他のものではない場合、これはそれらにも適用されます。

では、名前空間エイリアスは本当にエイリアスなのか、それとも別の意味の誤称なのか? それとも、このように専門化できない他の理由がありますか? もしそうなら、他の方法 (#defines の弾幕よりも良い) はありますか?

4

2 に答える 2

1

はい、namespaceエイリアスは本当にエイリアスです。またはstd_specializeのエイリアスとして宣言し、同じ名前でa を宣言しようとしているため、エラーが発生しています。それが合法である場合、その宣言の後、 (または)、またはあなたの専門化を含む新しい名前空間を参照するものは何ですか?stdstd::tr1namespacestd_specializestdstd::tr1hash

あなたがおそらくやりたいことは

namespace std {
#if __cplusplus < 201103L
namespace tr1 {
#endif

template<>
struct hash<my_type> { ... };

#if __cplusplus < 201103L
}
#endif
}
于 2013-09-26T20:02:04.420 に答える