如何为某些特定数据类型重载运算符?

时间:2015-11-12 12:33:44

标签: c++

考虑这段代码

#include <bits/stdc++.h>
using namespace std;

struct foo {
    template <typename T>
    foo& operator<< (const T& var) {
        cout << var;
        return *this;
    }
} bar;

int main() {
    bar << 1 << '\n';
    bar << 1.2 << '\n';
    return 0;
}

我想仅对整数数据类型重载<<运算符。 (int16_tint32_tint64_t
我怎么能这样做?

1 个答案:

答案 0 :(得分:6)

您可以使用SFINAE确保T是一个整数类型:

template <typename T>
std::enable_if_t<std::is_integral<T>::value, foo&> 
operator<< (const T& var) {
    cout << var;
    return *this;
}

或者,您可以使用static_assert

template <typename T>
foo& operator<< (const T& var) {
    static_assert(std::is_integral<T>::value, "T must be an integral type"); 
    cout << var;
    return *this;
}

请注意, #include来自bits文件夹的任何内容都是非便携式的。

如果要为积分和浮点类型分别进行重载,可以进行两次重载并使用SFINAE进行选择:

template <typename T>
std::enable_if_t<std::is_integral<T>::value, foo&>
operator<< (const T& var) {
    cout << "int " << var;
    return *this;
}

template <typename T>
std::enable_if_t<std::is_floating_point<T>::value, foo&>
operator<< (const T& var) {
    cout << "float " << var;
    return *this;
}

当我们获得Concepts时,您将能够编写如下内容:

template <Integral T>
//        ^^^^^^^^ Integral rather than typename
foo& operator<< (const T& var) {
    cout << var;
    return *this;
}