いくつかの型を取り、それを文字列表現に変換するオーバーロードされたグローバルto_string()
関数がいくつか必要です。T
一般的なケースでは、次のように記述できるようにしたいと考えています。
template<typename T,class OutputStringType> inline
typename enable_if<!std::is_pointer<T>::value
&& has_insertion_operator<T>::value,
void>::type
to_string( T const &t, OutputStringType *out ) {
std::ostringstream o;
o << t;
*out = o.str();
}
has_insertion_operator
これまでの私の実装は次のとおりです。
struct sfinae_base {
typedef char yes[1];
typedef char no[2];
};
template<typename T>
struct has_insertion_operator : sfinae_base {
template<typename U> static yes& test( U& );
template<typename U> static no& test(...);
static std::ostream &s;
static T const &t;
static bool const value = sizeof( test( s << t ) ) == sizeof( yes ); // line 48
};
(これ
とこれから借りています。)それはうまくいくようです。しかし今、私はオーバーロードされたバージョンのto_string
forを持ちたいのですが、独自のメンバー関数を持っていません。つまり:operator<<
to_string()
template<class T,class OutputStringType> inline
typename enable_if<!has_insertion_operator<T>::value
&& has_to_string<T,std::string (T::*)() const>::value,
void>::type
to_string( T const &t, OutputStringType *out ) {
*out = t.to_string();
}
の実装has_to_string
は次のとおりです。
#define DECL_HAS_MEM_FN(FN_NAME) \
template<typename T,typename S> \
struct has_##FN_NAME : sfinae_base { \
template<typename SignatureType,SignatureType> struct type_check; \
template<class U> static yes& test(type_check<S,&U::FN_NAME>*); \
template<class U> static no& test(...); \
static bool const value = sizeof( test<T>(0) ) == sizeof( yes ); \
}
DECL_HAS_MEM_FN( to_string );
(この部分は正常に動作しているようです。これはthisから適応されています。)ただし、次の場合:
struct S {
string to_string() const {
return "42";
}
};
int main() {
string buf;
S s;
to_string( s, &buf ); // line 104
}
私は得る:
foo.cpp: In instantiation of ‘const bool has_insertion_operator<S>::value’:
foo.cpp:104: instantiated from here
foo.cpp:48: error: no match for ‘operator<<’ in ‘has_insertion_operator<S>::s << has_insertion_operator<S>::t’
SFINAEは起きていないようです。グローバルが利用可能かhas_insertion_operator
どうかを判断するように正しく記述するにはどうすればよいですか?operator<<
参考までに: g++ 4.2.1 (Mac OS X の Xcode の一部として出荷されるもの) を使用しています。また、Boost などのサードパーティ ライブラリを使用せずに、コードを標準の C++03 のみにしたいと考えています。
ありがとう!