1

I am writing code to compare to instances of various types. The final comparison function is quite simple - with signature:

template <typename T>
int not_equal(const T& arg1, const T& arg2) {
    if (arg1 == arg2)
        return 0;

    std::cerr << "Error when comparing" << std::endl;
    return 1;
}

Now - I would like to add the actual values being compared in the std::cerr message as:

std::cerr << "Error when comparing " << arg1 << " != " << arg2 << std::endl;

however - many of the classes do not have operator<< - and that is OK. For the classes which do not support operator<< I just want the classname - i.e. the pseudo code should be something like:

if (supports_operator<<<T>)
    std::cerr << "Error when comparing " << arg1 << " != " << arg2 << std::endl;
else
    std::cerr << "Error when comparing instances of type: " << typeid(arg1).name() << std::endl;

Can I have my fictitious supports_operator<<<T>()functionality?

Edit: I am limited to C++17

Andreas
  • 5,050
  • 8
  • 42
  • 51
user422005
  • 1,840
  • 15
  • 30

1 Answers1

0

If you are able to use C++20 and concepts, then you can do something like this:

#include <iostream>
#include <concepts>

template <typename T> 
concept Streamable = requires (T x) { std::cout << x; };

struct Foo {};
struct Bar {};

std::ostream& operator<<(std::ostream& os, Foo const& obj) {
    // write obj to stream
    return os;
}

template <Streamable T>
void foo(T const& t) {
    std::cout << t << std::endl;
}

int main() {
    Foo f;
    Bar b;

    foo(f);
    foo(b); // error

    return 0; 
}

Demo

NutCracker
  • 10,520
  • 2
  • 39
  • 66