如何检测类型是否具有运算符<<重载?
How can I detect if a type has an operator << overload?
我想编写一个通用的打印模板,所以这个问题的更具体的措辞是:我如何确定某些operator<<
方法是否重载了类型?
这可以使用boost来完成。TypeTraits,特别是has_left_shift。一个例子:
#include <iostream>
#include "boost/type_traits.hpp"
struct foo
{
int i;
};
struct bar
{
int j;
};
std::ostream& operator<<(std::ostream& os, const foo& f)
{
return os << f.i;
}
int main()
{
// Prints out 1 == true
std::cout << boost::has_left_shift<std::ostream&, foo&, std::ostream&>::value << 'n';
// Prints out 0 == false
std::cout << boost::has_left_shift<std::ostream&, bar&, std::ostream&>::value << 'n';
}
但是,请注意文档底部列出的已知问题。
SFINAE可以帮助您检查是否提供了某个方法。
#include <iostream>
struct Generic {};
struct Printable{};
std::ostream& operator<<(std::ostream& o, const Printable& t) {
return o;
}
// SFINAE test
typedef char one;
typedef struct { char a[2]; } two;
template <typename T> static one printable_test(std::ostream&o, decltype (o << T{}, 0) ) ;
template <typename T> static two printable_test(...);
template <typename T> bool printable_with(std::ostream& o) {
return sizeof(printable_test<T>(o, 0)) == sizeof(one);
}
int main() {
std::cout << std::boolalpha << printable_with<Generic>(std::cout) << std::endl;
std::cout << std::boolalpha << printable_with<Printable>(std::cout) << std::endl;
return 0;
}
生活一些解释。有两个重载的函数模板printable_test
, printable_with()
中调用它们的重载解析结果会告诉结果。
第一个版本以decltype (o << T{}, 0)
作为第二个参数,只有在o << T{}
有效的情况下才有效,即在T
上提供了operator<<
,然后decltype
将以0
(逗号表达式的最后一个表达式)作为其类型,因此该版本将最匹配调用。
否则,即未提供T
上的operator<<
,则采用第二版。
相关文章:
- 如何防止clang格式在流运算符调用之间添加换行符<<
- 如何显式调用运算符<<
- 为什么COUT在朋友函数中不起作用,该功能超载了操作员&lt;&lt;这是一个iStream运算符
- C++运算符<<调用::ostream而不是std::osttream
- BOOST ::变体无法解决运算符&lt;&lt;对于STD :: Ostream
- 过载输出<<用于类的运算符,以打印其中的元组
- C++ostream:没有运算符匹配<<&应在'&'代币
- 重载运算符<<:此运算符函数的参数太多
- C++继承运算符<<
- 重载运算符<<用于模板类.即使使用好友关键字也无法获得私人会员
- 如何过载<<用于YAML::Emitter的运算符,以序列化包含另一个自定义类的向量的自定义类
- 为什么字符串流运算符<<擦除原始值
- 关于使用运算符<<为新手提供C++中的模板
- 我已经完成了<<运算符重载,但它'It’不起作用
- 重载运算符<<输出地址而不是数据成员
- 错误:没有匹配'运算符<<"在'std::cout
- 重载运算符<<用于ostream语法
- 当运算符<存在时,为什么要定义 LT?
- log4cxx访问异常,使用<<运算符和宏
- 重载<<运算符错误C2804:二进制'运算符<<'参数太多