Skip to content

Commit 647dc89

Browse files
committed
c++ fix dynamic exception c++17 build error, split some stuff
1 parent a0683c0 commit 647dc89

5 files changed

Lines changed: 187 additions & 114 deletions

File tree

‎cpp/README.md‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@
3535
1. [Most vexing parse](most_vexing_parse.cpp)
3636
1. [Delegating constructor](delegating_constructor.cpp)
3737
1. [Implicitly deleted constructor](implicitly_deleted_constructor.cpp)
38+
1. [Constructor init object member](constructor_init_object_member.cpp)
39+
1. [Initializer list constructor](initializer_list_constructor.cpp)
3840
1. Inheritance
3941
1. [Inheritance override](inheritance_override.cpp)
4042
1. [Inherit overload_hide](inherit_overload_hide.cpp)

‎cpp/class.cpp‎

Lines changed: 1 addition & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -196,31 +196,6 @@ class UniformInitializationList {
196196
}
197197
};
198198

199-
#if __cplusplus >= 201103L
200-
201-
/**
202-
This class has an `Initializer_list` constructor.
203-
*/
204-
class InitializerListCtor {
205-
public:
206-
207-
std::vector<int> v;
208-
209-
InitializerListCtor(std::initializer_list<int> list) {
210-
for (auto& i : list)
211-
v.push_back(i);
212-
}
213-
214-
InitializerListCtor(int before, std::initializer_list<int> list, int after) {
215-
v.push_back(before + 1);
216-
for (auto& i : list)
217-
v.push_back(i);
218-
v.push_back(after - 1);
219-
}
220-
};
221-
222-
#endif
223-
224199
class MemberConstructorTest {
225200
public:
226201
NoBaseNoMember0 member0;
@@ -284,6 +259,7 @@ class Base {
284259
Initialization lists have 4 main uses:
285260
286261
1) avoid calling member object constructor and copy separately
262+
https://stackoverflow.com/questions/12927169/how-can-i-initialize-c-object-member-variables-in-the-constructor
287263
2) initializing base classes with non default constructors
288264
3) initializing const elements
289265
4) initializing member references &
@@ -1184,95 +1160,6 @@ int main() {
11841160
#endif
11851161
}
11861162

1187-
#if __cplusplus >= 201103L
1188-
/*
1189-
# Brace enclosed initializer list
1190-
1191-
See inializer list
1192-
1193-
# List initialization
1194-
1195-
See initializer list constructor.
1196-
1197-
# Initializer list contructor
1198-
1199-
Useful in cases where you don't know beforehand how many arguments
1200-
a constructor should receive.
1201-
1202-
For example, the stdlib std::vector class gets an initializer list constructor on C++11,
1203-
which allows one to initialize it to any constant.
1204-
1205-
TODO could this not be achieved via cstdarg?
1206-
*/
1207-
{
1208-
//STL std::vector usage example
1209-
{
1210-
std::vector<int> v{0, 1};
1211-
// SAME.
1212-
//std::vector<int> v = std::vector<int>({0, 1});
1213-
assert(v[0] == 0);
1214-
assert(v[1] == 1);
1215-
assert(v == std::vector<int>({0, 1}));
1216-
assert((v == std::vector<int>{0, 1}));
1217-
1218-
// Assignment also works via implicit conversion.
1219-
v = {1, 0};
1220-
assert((v == std::vector<int>{1, 0}));
1221-
1222-
// ERROR: TODO why no implicit conversion is made?
1223-
//assert((v == {0, 1}));
1224-
}
1225-
1226-
// How to implemente one.
1227-
{
1228-
{
1229-
InitializerListCtor o{0, 1};
1230-
assert((o.v == std::vector<int>{0, 1}));
1231-
}
1232-
1233-
// Initializer list constructor is called
1234-
{
1235-
InitializerListCtor o{0, 0, 0, 0};
1236-
assert((o.v == std::vector<int>{0, 0, 0, 0}));
1237-
}
1238-
1239-
// 3 param constructor is called
1240-
{
1241-
InitializerListCtor o(0, {0, 0,}, 0);
1242-
assert((o.v == std::vector<int>{1, 0, 0, -1}));
1243-
}
1244-
}
1245-
1246-
/*
1247-
# auto and initializer lists
1248-
1249-
auto rule: brace initializer can be bound to auto
1250-
1251-
http://en.cppreference.com/w/cpp/utility/initializer_list
1252-
*/
1253-
{
1254-
{
1255-
// TODO GCC 5.1 does not allow this, which conflicts with
1256-
// http://en.cppreference.com/w/cpp/utility/initializer_list
1257-
// Who is right?
1258-
//auto l{0, 1, 2};
1259-
// SAME:
1260-
//initializer_list<int> l{0, 1, 2};
1261-
//assert(l.size() == 3);
1262-
//assert(*l.begin() == 0);
1263-
}
1264-
1265-
// The rule for auto makes this ranged for work.
1266-
// TODO0 why here? I see an `int`, not an `auto`
1267-
int i = 0;
1268-
for (int x : {0, 1, 2}) {
1269-
assert(x == i);
1270-
i++;
1271-
}
1272-
}
1273-
}
1274-
#endif
1275-
12761163
/*
12771164
# Destructor
12781165
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
https://stackoverflow.com/questions/12927169/how-can-i-initialize-c-object-member-variables-in-the-constructor
3+
4+
Initializer lists are the only way to not call the extra default constructor + assignement apparently.
5+
This is a major use case of initializer lists.
6+
7+
They are not very versatile however, as you can't easily have multiple statements.
8+
*/
9+
10+
#include "common.hpp"
11+
12+
class MyMemberClass {
13+
public:
14+
int i;
15+
MyMemberClass() : i(0) {
16+
callStack.push_back("MyMemberClass()");
17+
}
18+
MyMemberClass(int i) : i(i) {
19+
callStack.push_back("MyMemberClass(int i)");
20+
}
21+
MyMemberClass& operator=(const MyMemberClass& rhs) {
22+
this->i = rhs.i;
23+
callStack.push_back("operator=");
24+
return *this;
25+
}
26+
};
27+
28+
class MyClass {
29+
public:
30+
MyMemberClass myMemberClass;
31+
MyClass(int i) : myMemberClass(i) {}
32+
};
33+
34+
class MyClassNoInitializer {
35+
public:
36+
MyMemberClass myMemberClass;
37+
MyClassNoInitializer(int i) {
38+
myMemberClass = MyMemberClass(i);
39+
}
40+
};
41+
42+
int main() {
43+
// Good, less calls.
44+
{
45+
callStack.clear();
46+
MyClass myClass(1);
47+
assert(myClass.myMemberClass.i == 1);
48+
assert(callStack.size() == 1);
49+
assert(callStack.back() == "MyMemberClass(int i)");
50+
}
51+
52+
// Bad, more calls.
53+
{
54+
callStack.clear();
55+
MyClassNoInitializer myClass(2);
56+
assert(myClass.myMemberClass.i == 2);
57+
assert(callStack.size() == 3);
58+
}
59+
}

‎cpp/exception.cpp‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ class myexception: public std::exception {
5050
// All exceptions are catchable (default):
5151
void exception_func_all() { throw 0; }
5252

53+
#if __cplusplus < 201703L
5354
// Only int exceptions are catchable
5455
void exception_func_int_only(bool throw_int) throw (int) {
5556
if (throw_int)
@@ -66,6 +67,7 @@ void exception_func_int_exception_only(int which) throw (int, std::exception) {
6667
default: throw 'c'; break;
6768
}
6869
}
70+
#endif
6971

7072
// No exceptions are catchable
7173
void exception_func_none() throw() {throw 1;}
@@ -201,10 +203,15 @@ int main() {
201203
//throw myexception();
202204
}
203205

206+
#if __cplusplus < 201703L
204207
/*
205208
# exception specifications
206209
207210
Functions can specify which exceptions are catchable with the following syntax.
211+
212+
Deprecated since C++11, removed in C++17, noexcept is favored instead.
213+
214+
https://stackoverflow.com/questions/47284705/c1z-dynamic-exception-specification-error
208215
*/
209216
{
210217
try {
@@ -240,6 +247,7 @@ int main() {
240247
/* the same goes if we wrap the function */
241248
}
242249
}
250+
#endif
243251

244252
/*
245253
# exception from destructor
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
/*
2+
# Brace enclosed initializer list
3+
4+
See inializer list
5+
6+
# List initialization
7+
8+
See initializer list constructor.
9+
10+
# Initializer list contructor
11+
12+
Applications:
13+
14+
- you don't know beforehand how many arguments a constructor should receive
15+
16+
For example, the stdlib std::vector class gets an initializer list constructor on C++11,
17+
which allows one to initialize it to any constant.
18+
19+
TODO could this not be achieved via cstdarg?
20+
21+
- nice shorthand that omits typing types multiple times.
22+
*/
23+
24+
#include "common.hpp"
25+
26+
#if __cplusplus >= 201103L
27+
/**
28+
* This class has an `Initializer_list` constructor.
29+
*/
30+
class InitializerListCtor {
31+
public:
32+
33+
std::vector<int> v;
34+
35+
InitializerListCtor(std::initializer_list<int> list) {
36+
for (auto& i : list)
37+
v.push_back(i);
38+
}
39+
40+
InitializerListCtor(int before, std::initializer_list<int> list, int after) {
41+
v.push_back(before + 1);
42+
for (auto& i : list)
43+
v.push_back(i);
44+
v.push_back(after - 1);
45+
}
46+
};
47+
#endif
48+
49+
int main() {
50+
#if __cplusplus >= 201103L
51+
//STL std::vector usage example
52+
{
53+
std::vector<int> v{0, 1};
54+
// SAME.
55+
//std::vector<int> v = std::vector<int>({0, 1});
56+
assert(v[0] == 0);
57+
assert(v[1] == 1);
58+
assert(v == std::vector<int>({0, 1}));
59+
assert((v == std::vector<int>{0, 1}));
60+
61+
// Assignment also works via implicit conversion.
62+
v = {1, 0};
63+
assert((v == std::vector<int>{1, 0}));
64+
65+
// ERROR: TODO why no implicit conversion is made?
66+
//assert((v == {0, 1}));
67+
}
68+
69+
// How to implemente one.
70+
{
71+
{
72+
InitializerListCtor o{0, 1};
73+
assert((o.v == std::vector<int>{0, 1}));
74+
}
75+
76+
// Initializer list constructor is called
77+
{
78+
InitializerListCtor o{0, 0, 0, 0};
79+
assert((o.v == std::vector<int>{0, 0, 0, 0}));
80+
}
81+
82+
// 3 param constructor is called
83+
{
84+
InitializerListCtor o(0, {0, 0,}, 0);
85+
assert((o.v == std::vector<int>{1, 0, 0, -1}));
86+
}
87+
}
88+
89+
/*
90+
# auto and initializer lists
91+
92+
auto rule: brace initializer can be bound to auto
93+
94+
http://en.cppreference.com/w/cpp/utility/initializer_list
95+
*/
96+
{
97+
{
98+
// TODO GCC 5.1 does not allow this, which conflicts with
99+
// http://en.cppreference.com/w/cpp/utility/initializer_list
100+
// Who is right?
101+
//auto l{0, 1, 2};
102+
// SAME:
103+
//initializer_list<int> l{0, 1, 2};
104+
//assert(l.size() == 3);
105+
//assert(*l.begin() == 0);
106+
}
107+
108+
// The rule for auto makes this ranged for work.
109+
// TODO0 why here? I see an `int`, not an `auto`
110+
int i = 0;
111+
for (int x : {0, 1, 2}) {
112+
assert(x == i);
113+
i++;
114+
}
115+
}
116+
#endif
117+
}

0 commit comments

Comments
 (0)