SFINAE过载选择是否有操作符<<?

Vin*_*ent 1 c++ operators sfinae enable-if c++11

考虑这两个功能:

template <class Type, 
          class = typename std::enable_if</*HAS OPERATOR <<*/>::type>
void f(std::ostream& stream, const Type& value);

template <class Type, 
          class... DummyTypes,
          class = typename std::enable_if<sizeof...(DummyTypes) == 0>::type>
void f(std::ostream& stream, const Type& value, DummyTypes...);
Run Code Online (Sandbox Code Playgroud)

由于非可变重载优先于可变参数重载,我想检查类型是否在第一个版本中operator<<具有std::ostream使用std::enable_if.

那我该怎么写而不是/*HAS OPERATOR <<*/

Dan*_*rey 6

以下应该有效

template <class Type, 
          class = decltype(std::declval<std::ostream&>() << std::declval<Type>())>
void f(std::ostream& stream, const Type& value)
{
    stream << value;
}
Run Code Online (Sandbox Code Playgroud)

(注意std::enable_if在这种情况下你不需要使用)


Mat*_* M. 6

使用尾随返回类型(1),您实际上可以预先考虑概念:

template <typename Type>
auto f(std::ostream& out, Type const& t) -> decltype(out << t, void()) {
    // ...
}
Run Code Online (Sandbox Code Playgroud)

由于SFINAE,只有在out << t可以解析的类型时才能选择此重载,这意味着<<存在接受两个参数的重载.

一个缺陷是,如果您需要相反的情况,这不起作用,即如果此过载不存在则启用函数.在这种情况下,据我所知,enable_if策略(和对称disable_if)是必要的.

(1)感谢Simple帮助解决语法问题