-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathsfinae_tostring.cpp
50 lines (42 loc) · 1.3 KB
/
sfinae_tostring.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
// sfinae_tostring.cpp : use of SFINAE with traits and enable_if
// note: compile with -std=c++20 or later
#include <type_traits>
#include <iostream>
#include <string>
#include <initializer_list>
#include <vector>
using namespace std;
class Book {
string d_title;
vector<string> d_authors;
public:
Book(const string& title, const initializer_list<string>& authors)
: d_title{ title }, d_authors{ authors }
{}
string to_string() const {
string s{}, sep{};
for (const auto& a : d_authors) {
s.append(sep);
s.append(a);
sep = ", "s;
}
s.append(": ");
s.append(d_title);
return s;
}
};
template<typename, typename = std::void_t<>>
struct HasMemberT_toString : false_type{};
template<typename T>
struct HasMemberT_toString<T, void_t<decltype(declval<T>().to_string())>> : true_type{};
static_assert(HasMemberT_toString<Book>::value);
template<typename T>
enable_if<HasMemberT_toString<T>::value, ostream&>::type
operator<< (ostream& os, const T& obj) {
return os << obj.to_string();
}
int main() {
Book book1{ "C++ Annotations", { "Frank B. Brokken" } },
book2{ "C++ Templates", { "David Vandevoorde", "Nicolai M. Josuttis", "Douglas Gregor" } };
cout << book1 << '\n' << book2 << '\n';
}