我想编写一个通用的打印模板,因此问题的更具体的措辞是:我如何确定某个类型的某些operator<<
方法是否超载?
答案 0 :(得分:5)
这可以使用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';
}
请注意已知问题,这些问题列在文档的底部。
答案 1 :(得分:0)
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;
}
一些解释。
重新加载2个函数模板printable_test
,在printable_with()
中调用它们的重载解析结果将告诉结果。
第一个版本将decltype (o << T{}, 0)
作为其第二个参数,仅当o << T{}
有效时才有效,即提供operator<<
上的T
,然后{{1将decltype
(逗号表达式的最后一个表达式)作为其类型,因此该版本将匹配最佳调用。
否则,即未提供0
operator<<
,将采用第二版。