类型特征以检查是否可从流和MSVC读取类型

时间:2018-09-04 19:05:55

标签: c++ typetraits

最近我遇到了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.2clang 6.0.0,但第二个断言是MSVC rejects

我想知道我的实现(或测试)是否不正确,或者是MSVC的另一个问题。

1 个答案:

答案 0 :(得分:6)

这里的问题是MSVS可以将右值绑定到左值引用作为语言扩展。编译以下代码:

struct readable{ };

void foo(readable&)
{ }

void bar()
{
    foo(readable{});
}

使用可以使用/Za选项(禁用语言扩展)来禁用它。然后您的主张将被传递。