avamsi
avamsi

Reputation: 399

How do I overload operators for some specific data types?

Consider this code

#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;
}

I want to overload << operator only for integer data types. (int16_t, int32_t, int64_t)
How can I do that?

Upvotes: 0

Views: 56

Answers (1)

TartanLlama
TartanLlama

Reputation: 65640

You can use SFINAE to ensure that T is an integral type:

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

Alternatively, you can use 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;
}

Note that you should not #include anything from the bits folder, that's non-portable.


If you want separate overloads for integral and floating point types, you can make two overloads and select with 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;
}

When we get Concepts you'll be able to write something like this:

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

Upvotes: 6

Related Questions