Pau*_*cas 11 c++ templates sfinae
我想有几个重载的全局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();
}
Run Code Online (Sandbox Code Playgroud)
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
};
Run Code Online (Sandbox Code Playgroud)
(它借鉴了这个
和这个.)这似乎有效.但现在我想有一个重载版本的to_string用于那些类型不会有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();
}
Run Code Online (Sandbox Code Playgroud)
执行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 );
Run Code Online (Sandbox Code Playgroud)
(这部分似乎做工精细它是从调整.这个).但是,当我有:
struct S {
string to_string() const {
return "42";
}
};
int main() {
string buf;
S s;
to_string( s, &buf ); // line 104
}
Run Code Online (Sandbox Code Playgroud)
我明白了:
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’
Run Code Online (Sandbox Code Playgroud)
似乎SFINAE没有发生.如何has_insertion_operator正确编写以确定全局operator<<是否可用?
仅供参考:我正在使用g ++ 4.2.1(在Mac OS X上作为Xcode的一部分提供).此外,我希望代码只是没有第三方库的标准C++ 03,例如Boost.
谢谢!
我应该更加忠实于这个答案.一个有效的实施是:
namespace has_insertion_operator_impl {
typedef char no;
typedef char yes[2];
struct any_t {
template<typename T> any_t( T const& );
};
no operator<<( std::ostream const&, any_t const& );
yes& test( std::ostream& );
no test( no );
template<typename T>
struct has_insertion_operator {
static std::ostream &s;
static T const &t;
static bool const value = sizeof( test(s << t) ) == sizeof( yes );
};
}
template<typename T>
struct has_insertion_operator :
has_insertion_operator_impl::has_insertion_operator<T> {
};
Run Code Online (Sandbox Code Playgroud)
我相信,它并没有真正依靠SFINAE.
| 归档时间: |
|
| 查看次数: |
2900 次 |
| 最近记录: |