且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

检查c ++ 11中是否存在运算符的***方法

更新时间:2023-11-26 15:11:04

速成C ++ 11 SFINAE:

Quick-and-dirty C++11 SFINAE:

template<typename T,
         typename = decltype(
           std::declval<std::ostream&>() << std::declval<T const&>()
         )
>
std::string toString(T const& t)
{
    std::ostringstream out;
    // Beware of no error checking here
    out << t;
    return out.str();
}

template<typename T,
         typename... Ignored
>
std::string toString(T const& t, Ignored const&..., ...)
{
    static_assert( sizeof...(Ignored) == 0
                 , "Incorrect usage: only one parameter allowed" );
    /* handle any which way here */
}

如果需要,还可以检查stream << val的返回类型确实可以转换为std::ostream&:

If you want you can also check that the return type of stream << val is indeed convertible to std::ostream&:

template<typename T,
         typename Result = decltype(
           std::declval<std::ostream&>() << std::declval<T const&>()
         ),
         typename std::enable_if<
             std::is_convertible<Result, std::ostream&>::value,
             int
         >::type = 0
>

对于不是那么简单的解决方案,我将引入is_stream_insertable特征,该特征可以利用此处使用的相同技巧.

As for a not so quick-and-dirty solution I'd introduce an is_stream_insertable trait, which implementation can make use of the very same tricks used here.

请注意,std::integral_constant<bool, B>具有到bool的转换运算符,这可能可以解释您所观察到的某些情况.我也不建议将C ++ 11标准类型和特征与Boost混合使用:不要将std::true_typeboost::true_type混合使用!这并不是说您不应该使用例如Boost.TypeTraits与C ++ 11完全兼容,但要保持一致,并且一次只能使用两个.

Be aware that std::integral_constant<bool, B> has a conversion operator to bool, this might explain some of the things you have observed. I also do not recommend mixing the C++11 Standard types and traits with Boost: don't mix up std::true_type with boost::true_type! Which is not to say that you shouldn't use e.g. Boost.TypeTraits at all with C++11, but try to be consistent and only use one of two at a time.