如何检测类型是否具有运算符<<超载?

时间:2015-10-12 03:52:33

标签: c++ templates

我想编写一个通用的打印模板,因此问题的更具体的措辞是:我如何确定某个类型的某些operator<<方法是否超载?

2 个答案:

答案 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;
}

LIVE

一些解释。

重新加载2个函数模板printable_test,在printable_with()中调用它们的重载解析结果将告诉结果。

第一个版本将decltype (o << T{}, 0)作为其第二个参数,仅当o << T{}有效时才有效,即提供operator<<上的T,然后{{1将decltype(逗号表达式的最后一个表达式)作为其类型,因此该版本将匹配最佳调用。

否则,即未提供0 operator<<,将采用第二版。