c – 使用SFINAE检查全局运算符<<?
发布时间:2020-12-16 09:09:46 所属栏目:百科 来源:网络整理
导读:我想有几个重载的全局to_string()函数,它们采用某种类型T并将其转换为其字符串表示形式.对于一般情况,我希望能够写: templatetypename T,class OutputStringType inlinetypename enable_if!std::is_pointerT::value has_insertion_operatorT::value,void::t
我想有几个重载的全局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 }; (它借鉴了this template<class T,class OutputStringType> inline typename enable_if<!has_insertion_operator<T>::value && has_to_string<T,std::string (T::*)() const>::value,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,以确定是否为全局运算符<<可以吗? 仅供参考:我正在使用g 4.2.1(在Mac OS X上作为Xcode的一部分提供). 谢谢! 解决方法
我应该更忠实于
this答案.
一个有效的实施是: 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> { }; 我相信它实际上并不依赖于SFINAE. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |