是否有一种方法可以检查ostream << T是否为类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构造模板?
发布于 2018-07-08 00:09:01
这样做的蓝图是从以下几个方面开始:
#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类将提供自己的<<方法,该方法将其成员传递给父类的方法,该方法将为支持<<的类完全定义,而如果试图引用未实现<<重载的类,则会导致编译错误。
https://stackoverflow.com/questions/51227804
复制相似问题