更新时间: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_type
与boost::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.