SFINAE を有利に使用する方法を学んでいます。オブジェクト内の関数の存在に基づいて関数の実装を選択するために使用しようとしてserialize()
います。
これは、型が serialize() 関数を定義しているかどうかを判断するために使用するコードです。
template <typename T>
class HasSerialize {
private:
typedef char yes[1];
typedef char no[2];
template <typename C> static yes& test(char[sizeof(&C::serialize)]) ;
template <typename C> static no& test(...);
public:
static const bool value = sizeof(test<T>(0)) == sizeof(yes);
};
ただし、GCC と Clang では正反対の結果が得られるようです。次のコードを想定します。
template<bool T>
class NVPtypeSerializer {
public:
template<typename C>
static xmlChar* serialize(C value) {
// serize() is not available
}
};
template<>
struct NVPtypeSerializer<true> {
public:
template<typename T>
static xmlChar* serialize(T value) {
return value.serialize();
}
};
これは次のように呼び出されます:
foo = NVPtypeSerializer<HasSerialize<Bar>::value >::serialize(value);
クラスBar
に機能がないserialize()
場合。このコードは Clang 3.1 では正常にコンパイルされますが、GCC 4.7.1 では次のエラーが発生します。
error: ‘class Bar’ has no member named ‘serialize’
に変更するstruct NVPtypeSerializer<true>
とstruct NVPtypeSerializer<false>
、GCC でコンパイルできますが、Clang で次のエラーが発生します。
error: no member named 'serialize' in 'Bar'
問題はどこだ?それは私のコードにありますか?コードをできるだけ移植できるようにしたいと思います。