最近我遇到了the question讨论了 is_streamable
类型特征。所以我决定实现我自己的版本并提出下一个解决方案来检查是否可以从 std::istream
读取类型:
template<typename, typename = void>
struct is_readable_from_stream_impl
: std::false_type {};
template<typename T>
struct is_readable_from_stream_impl<T,
std::void_t<decltype(std::declval<std::istream&>() >> std::declval<T>())>>
: std::true_type {};
template<typename T>
struct is_readable_from_stream :
is_readable_from_stream_impl<T> {};
template<typename T>
inline constexpr auto is_readable_from_stream_v = is_readable_from_stream<T>::value;
到目前为止,还不错。然后我添加了一个带有重载 operator>>
的自定义结构:
struct readable {};
std::istream& operator>>(std::istream& is, readable&)
{
return is;
}
并测试了类型特征:
static_assert(is_readable_from_stream_v<readable&>);
static_assert(!is_readable_from_stream_v<readable>);
检查通过了 gcc 8.2
和 clang 6.0.0
,但是 MSVC
rejects第二个断言。
我想知道我的实现(或测试)是否不正确,或者这是 MSVC
的另一个问题。
最佳答案
这里的问题是 MSVS 可以将右值绑定(bind)到左值引用作为语言扩展。编译以下代码:
struct readable{ };
void foo(readable&)
{ }
void bar()
{
foo(readable{});
}
使用可以使用/Za
选项(Disable Language Extensions)来禁用它。然后你的断言将被传递。
关于c++ - 类型特征以检查类型是否可从流和 MSVC 中读取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52172563/