#include <iostream>
#include <utility>
template <typename T>
concept Printable = requires(const T &x) {
{ std::cout << x } -> std::same_as<std::ostream &>;
};
template <Printable T1, Printable T2>
std::ostream &operator<<(std::ostream &os, const std::pair<T1, T2> &x) {
return os << "(" << x.first << ", " << x.second << ")";
}
static_assert(Printable<std::pair<int, int>>); // fails because 'std::pair<int, int>' does not satisfy 'Printable'
A concept Printable
indicates that a type can be printed to standard output.
std::pair<T1, T2>
is expected to be Printable whenever T1
and T2
are both Printable.
However, static_assert(Printable<std::pair<int, int>>)
fails. Why and how do I fix it?
More precisely, what I want to do is:
#include <iostream>
#include <utility>
#include <vector>
template <typename T>
concept Printable = requires(const T &x) {
{ std::cout << x } -> std::same_as<std::ostream &>;
};
template <Printable T1, Printable T2>
std::ostream &operator<<(std::ostream &os, const std::pair<T1, T2> &x) {
return os << "(" << x.first << ", " << x.second << ")";
}
template <Printable T>
std::ostream &operator<<(std::ostream &os, const std::vector<T> &v) {
for (const auto &e : v) os << e;
return os;
}
// I want these assertions all to succeed.
static_assert(Printable<std::pair<int, std::vector<int>>>);
static_assert(Printable<std::vector<std::pair<int, int>>>);
static_assert(Printable<std::vector<std::vector<std::vector<int>>>>);