作者:我的王国1997_113 | 来源:互联网 | 2022-12-05 17:42
最近我遇到了讨论is_streamable
类型特征的问题.所以我决定实现我自己的版本并提出下一个解决方案来检查是否可以读取类型std::istream
:
template
struct is_readable_from_stream_impl
: std::false_type {};
template
struct is_readable_from_stream_impl() >> std::declval())>>
: std::true_type {};
template
struct is_readable_from_stream :
is_readable_from_stream_impl {};
template
inline constexpr auto is_readable_from_stream_v = is_readable_from_stream::value;
到现在为止还挺好.我添加了一个重载的自定义结构operator>>
:
struct readable {};
std::istream& operator>>(std::istream& is, readable&)
{
return is;
}
并测试了类型特征:
static_assert(is_readable_from_stream_v);
static_assert(!is_readable_from_stream_v);
该检查用均通过gcc 8.2
和clang 6.0.0
,但MSVC
拒绝第二个断言.
我想知道我的实现(或测试)是否不正确或者是另一个问题MSVC
.
1> Evg..:
这里的问题是MSVS可以将rvalues绑定到lvalue-references作为语言扩展.以下代码编译:
struct readable{ };
void foo(readable&)
{ }
void bar()
{
foo(readable{});
}
使用可以使用/Za
选项(禁用语言扩展)来禁用它.然后你的断言将被传递.
如果可以的话,我建议使用`/ permissive -`,而不仅仅是`/ Za`.它使MSVC在很多地方都符合标准,它通常不会这样做.
@Fureeish,是的,每个扩展的rvalues到lvalue-refs,按照标准的r值到const-lvalue-refs.