有没有办法检查是否为类 T 定义了 ostream << T 并使用该信息来决定是否构建模板?
例如,假设我有一些围绕不同类型 T 的包装类
template<class T>
Wrapper
{
public:
T m_value;
Wrapper(const T & value) : m_value{ value } { }
};
我想定义一个 operator<<() 友元函数来打印到 ostream
template<class T>
ostream & operator<<(ostream & out, const Wrapper<T> & wrapper)
{
out << wrapper.value;
return out;
}
有没有办法只为定义了 ostream << T 的类型 T 构建模板?
最佳答案
做这样的事情的蓝图是从这个开始:
#include <utility>
#include <iostream>
template<typename T, typename=void>
struct can_output_to_ostream : public std::false_type {};
template<typename T>
struct can_output_to_ostream<T, std::void_t
<decltype(std::declval<std::ostream &>() <<
std::declval<T &&>())>>
: public std::true_type{};
struct x {};
int main()
{
std::cout << can_output_to_ostream<int>::value << std::endl;
std::cout << can_output_to_ostream<x>::value << std::endl;
}
std::void_t
是C++17
,但通过简短的搜索可以找到在早期 C++ 修订版中实现它的示例。
这个例子的输出是:
1
0
因为你可以 <<
一个int
, 但没有为 x
定义这样的重载.
在您的情况下,您可以使用此示例并让包装类继承自 implements_output_to_ostream
以类似方式定义的类。默认实现什么也不做,一个用于 <<
有能力的类实现了<<
相应的运营商。
你的 Wrapper
类继承自 implements_output_ostream
.也许你的 Wrapper
类将提供自己的 <<
将其成员传递给父类方法的方法,该方法将为 <<
完全定义有能力的类,否则未定义,如果尝试为未实现 <<
的类引用它,则会导致编译错误过载。
关于c++ - 检查是否为类 T 定义了 ostream << T,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51227804/