forked from cirosantilli/cpp-cheat
-
Notifications
You must be signed in to change notification settings - Fork 0
/
initializer_list_constructor.cpp
117 lines (93 loc) · 2.89 KB
/
initializer_list_constructor.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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
/*
# Brace enclosed initializer list
See inializer list
# List initialization
See initializer list constructor.
# Initializer list contructor
Applications:
- you don't know beforehand how many arguments a constructor should receive
For example, the stdlib std::vector class gets an initializer list constructor on C++11,
which allows one to initialize it to any constant.
TODO could this not be achieved via cstdarg?
- nice shorthand that omits typing types multiple times.
*/
#include "common.hpp"
#if __cplusplus >= 201103L
/**
* This class has an `Initializer_list` constructor.
*/
class InitializerListCtor {
public:
std::vector<int> v;
InitializerListCtor(std::initializer_list<int> list) {
for (auto& i : list)
v.push_back(i);
}
InitializerListCtor(int before, std::initializer_list<int> list, int after) {
v.push_back(before + 1);
for (auto& i : list)
v.push_back(i);
v.push_back(after - 1);
}
};
#endif
int main() {
#if __cplusplus >= 201103L
//STL std::vector usage example
{
std::vector<int> v{0, 1};
// SAME.
//std::vector<int> v = std::vector<int>({0, 1});
assert(v[0] == 0);
assert(v[1] == 1);
assert(v == std::vector<int>({0, 1}));
assert((v == std::vector<int>{0, 1}));
// Assignment also works via implicit conversion.
v = {1, 0};
assert((v == std::vector<int>{1, 0}));
// ERROR: TODO why no implicit conversion is made?
//assert((v == {0, 1}));
}
// How to implemente one.
{
{
InitializerListCtor o{0, 1};
assert((o.v == std::vector<int>{0, 1}));
}
// Initializer list constructor is called
{
InitializerListCtor o{0, 0, 0, 0};
assert((o.v == std::vector<int>{0, 0, 0, 0}));
}
// 3 param constructor is called
{
InitializerListCtor o(0, {0, 0,}, 0);
assert((o.v == std::vector<int>{1, 0, 0, -1}));
}
}
/*
# auto and initializer lists
auto rule: brace initializer can be bound to auto
http://en.cppreference.com/w/cpp/utility/initializer_list
*/
{
{
// TODO GCC 5.1 does not allow this, which conflicts with
// http://en.cppreference.com/w/cpp/utility/initializer_list
// Who is right?
//auto l{0, 1, 2};
// SAME:
//initializer_list<int> l{0, 1, 2};
//assert(l.size() == 3);
//assert(*l.begin() == 0);
}
// The rule for auto makes this ranged for work.
// TODO0 why here? I see an `int`, not an `auto`
int i = 0;
for (int x : {0, 1, 2}) {
assert(x == i);
i++;
}
}
#endif
}