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

标签 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 的另一个问题。

最佳答案

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

struct readable{ };

void foo(readable&)
{ }

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

使用可以使用/Za 选项(Disable Language Extensions)来禁用它。然后你的断言将被传递。

关于c++ - 类型特征以检查类型是否可从流和 MSVC 中读取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52172563/

相关文章:

c++ - 多级嵌套模板。我如何让它工作?

c++ - bool 和 sizeof 条件模板

c++ - 根据可用的参数使用一个或另一个重载的创建者

c++ - *(&a)=5 是什么意思?

c++ - 为什么 MinGW-w64 需要手动包含 winsock2?

c++ - 为什么从不可 move 类派生的类本身是可 move 构造的?

c# - "Promote"泛型类型在 C# 中为 Nullable?

c++ - std::map :使用自定义运算符时更新 key

c++ - 预编译头 - 从所有其他文件中删除所有预编译头所必需的

c++ - 可移动类型的类型特征?