Skip to content

Commit a358f5a

Browse files
committed
funtion definition and function pointer, learn and get used to their forms.
1 parent 95daf66 commit a358f5a

File tree

3 files changed

+151
-120
lines changed

3 files changed

+151
-120
lines changed

understanding-c++11/decltype.cpp

Lines changed: 114 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,65 @@
11
#include "decltype.h"
22

3-
NS_BEGIN(elloop)
4-
NS_BEGIN(decltype_test)
5-
6-
TEST(Decltype, TypeId) {
7-
// typeid requires RTTI mechanism.
8-
// to turn it off, use -fno-rttion in GCC, use /GR- in _MSC.
9-
TypeA a;
10-
TypeB b;
11-
TypeA c;
12-
psln(typeid(a).name());
13-
psln(typeid(b).name());
14-
15-
auto a_hash_code = typeid(a).hash_code();
16-
auto b_hash_code = typeid(b).hash_code();
17-
auto c_hash_code = typeid(c).hash_code();
18-
psln(typeid(a_hash_code).name()); // size_t
19-
EXPECT_EQ(a_hash_code, c_hash_code);
20-
EXPECT_NE(b_hash_code, c_hash_code);
3+
NS_BEGIN( elloop )
4+
NS_BEGIN( decltype_test )
5+
6+
TEST( Decltype, TypeId ) {
7+
// typeid requires RTTI mechanism.
8+
// to turn it off, use -fno-rttion in GCC, use /GR- in _MSC.
9+
TypeA a;
10+
TypeB b;
11+
TypeA c;
12+
psln( typeid(a).name() );
13+
psln( typeid(b).name() );
14+
15+
auto a_hash_code = typeid(a).hash_code();
16+
auto b_hash_code = typeid(b).hash_code();
17+
auto c_hash_code = typeid(c).hash_code();
18+
psln( typeid(a_hash_code).name() ); // size_t
19+
EXPECT_EQ( a_hash_code, c_hash_code );
20+
EXPECT_NE( b_hash_code, c_hash_code );
2121
}
2222

23-
TEST(Decltype, UsedInStandard) {
24-
// examples of using decltype in cpp11 standard.
25-
//using size_t = decltype(sizeof(0));
26-
//using ptrdiff_t = decltype((int*)0 - (int*)0);
27-
//using nullptr_t = decltype(nullptr);
28-
29-
// result_of<T> template is implemented base on decltype.
30-
typedef int(*func)(int, int);
31-
//std::result_of<func>::type f2; // error:
32-
std::result_of<func(int,int)>::type f2;
33-
//psln(typeid(f2).name()); // int
34-
bool same = std::is_same<decltype(f2), int>::value;
35-
EXPECT_TRUE(same);
36-
37-
EXPECT_EQ(typeid(int).hash_code(), typeid(f2).hash_code());
38-
23+
TEST( Decltype, UsedInStandard ) {
24+
// examples of using decltype in cpp11 standard.
25+
//using size_t = decltype(sizeof(0));
26+
//using ptrdiff_t = decltype((int*)0 - (int*)0);
27+
//using nullptr_t = decltype(nullptr);
28+
29+
// result_of<T> template is implemented base on decltype.
30+
typedef int( *func )(int, int);
31+
//std::result_of<func>::type f2; // error:
32+
std::result_of<func( int, int )>::type f2;
33+
//psln(typeid(f2).name()); // int
34+
bool same = std::is_same<decltype(f2), int>::value;
35+
EXPECT_TRUE( same );
36+
37+
EXPECT_EQ( typeid(int).hash_code(), typeid(f2).hash_code() );
38+
3939
}
4040

41-
TEST(Decltype, ReuseAnonymouseType) {
42-
// a_struct_value is a value of anonymouse struct type.
43-
decltype(a_struct_value) another;
44-
another.a = 100;
45-
EXPECT_EQ(100, another.a);
41+
TEST( Decltype, ReuseAnonymouseType ) {
42+
// a_struct_value is a value of anonymouse struct type.
43+
decltype(a_struct_value) another;
44+
another.a = 100;
45+
EXPECT_EQ( 100, another.a );
4646
}
4747

48-
TEST(Decltype, TemplateFunction) {
49-
int i(10);
50-
double d(1.2);
51-
double sumid(0);
52-
// restriction: sumid's type must be (i + d)'s type: double.
53-
Sum2(i, d, sumid);
54-
EXPECT_EQ(11.2, sumid);
48+
TEST( Decltype, TemplateFunction ) {
49+
int i( 10 );
50+
double d( 1.2 );
51+
double sumid( 0 );
52+
// restriction: sumid's type must be (i + d)'s type: double.
53+
Sum2( i, d, sumid );
54+
EXPECT_EQ( 11.2, sumid );
5555
}
5656

5757
TEST( Decltype, FourRulesForUsingDecltype ) {
5858
int i( 10 );
5959
int arr[10];
6060
int *ptr = arr;
6161
struct S { int si; } s;
62-
void foo(double);
62+
void foo( double );
6363
void foo( int );
6464
int && rvalueReference();
6565
const bool func( int );
@@ -85,15 +85,15 @@ TEST( Decltype, FourRulesForUsingDecltype ) {
8585

8686
//------------------------------------------------------
8787
// 2. e == xvalue --> decltype(e) == rvalue-reference.
88-
decltype(rvalueReference) v5; // int&& ();
89-
same = std::is_same<decltype(v5), int&& ()>::value;
90-
EXPECT_TRUE(same);
88+
decltype(rvalueReference) v5; // int&& ();
89+
same = std::is_same<decltype(v5), int&& ()>::value;
90+
EXPECT_TRUE( same );
9191

92-
decltype(rvalueReference()) v52 = 1; // int&&
92+
decltype(rvalueReference()) v52 = 1; // int&&
9393
same = std::is_same<decltype(v52), int&&>::value;
9494
EXPECT_TRUE( same );
9595
//------------------------------------------------------
96-
96+
9797
//------------------------------------------------------
9898
// 3. e --> lvalue --> decltype(e)==lvalue-reference.
9999
// following var must be bound with i, because they are all l-value-reference.
@@ -114,14 +114,14 @@ TEST( Decltype, FourRulesForUsingDecltype ) {
114114
EXPECT_TRUE( same );
115115

116116
decltype("hello") v10 = "12345"; // const char (&v10) [6];
117-
psln(typeid(v10).name());
118-
psln(typeid("hello").name());
119-
same = std::is_same<decltype(v10), const char(&)[5]>::value;
120-
EXPECT_FALSE(same);
121-
same = std::is_same<decltype(v10), const char(&)[6]>::value;
117+
psln( typeid(v10).name() );
118+
psln( typeid("hello").name() );
119+
same = std::is_same<decltype(v10), const char( &)[5]>::value;
120+
EXPECT_FALSE( same );
121+
same = std::is_same<decltype(v10), const char( &)[6]>::value;
122122
EXPECT_TRUE( same );
123-
same = std::is_same<decltype(v10), const char [6]>::value;
124-
EXPECT_FALSE(same);
123+
same = std::is_same<decltype(v10), const char[6]>::value;
124+
EXPECT_FALSE( same );
125125

126126
decltype(*ptr) v11 = i; // int&, operator* return l-value
127127
same = std::is_same<decltype(v11), int&>::value;
@@ -141,68 +141,68 @@ TEST( Decltype, FourRulesForUsingDecltype ) {
141141

142142
decltype(func( 1 )) v14 = 1000; // const bool
143143
same = std::is_same<decltype(v14), const bool>::value;
144-
EXPECT_FALSE(same);
145-
same = std::is_same<decltype(v14), bool>::value; // why const bool == bool?
146-
EXPECT_TRUE(same);
144+
EXPECT_FALSE( same );
145+
same = std::is_same<decltype(v14), bool>::value; // why const bool == bool?
146+
EXPECT_TRUE( same );
147147
//------------------------------------------------------
148148

149-
//---------------------- validate using is_lvalue_reference<T> ----------------------
150-
EXPECT_EQ(1, std::is_lvalue_reference<decltype(v6)>::value);
151-
EXPECT_EQ(1, std::is_lvalue_reference<decltype(v7)>::value);
152-
EXPECT_EQ(1, std::is_lvalue_reference<decltype(v8)>::value);
153-
EXPECT_EQ(1, std::is_lvalue_reference<decltype(v9)>::value);
149+
//---------------------- validate using is_lvalue_reference<T> ----------------------
150+
EXPECT_TRUE( std::is_lvalue_reference<decltype(v6)>::value );
151+
EXPECT_TRUE( std::is_lvalue_reference<decltype(v7)>::value );
152+
EXPECT_TRUE( std::is_lvalue_reference<decltype(v8)>::value );
153+
EXPECT_TRUE( std::is_lvalue_reference<decltype(v9)>::value );
154154

155-
EXPECT_EQ(1, std::is_rvalue_reference < decltype(v52) >::value);
155+
EXPECT_TRUE( std::is_rvalue_reference < decltype(v52) >::value );
156156
}
157157

158-
TEST(Decltype, CVQualifier) {
159-
// unlike auto keyword, decltype will be affected with c-v qualifier.
160-
const int ci = 10;
161-
volatile int vi;
162-
decltype(ci) i1 = 1;
163-
bool same = std::is_same<decltype(i1), const int>::value;
164-
EXPECT_TRUE(same);
165-
same = std::is_same<decltype(i1), int>::value;
166-
EXPECT_FALSE(same);
167-
EXPECT_EQ(1, std::is_const<decltype(i1)>::value);
168-
169-
decltype(vi) i2;
170-
same = std::is_same<decltype(i2), volatile int>::value;
171-
EXPECT_TRUE(same);
172-
EXPECT_EQ(1, std::is_volatile<decltype(i2)>::value);
158+
TEST( Decltype, CVQualifier ) {
159+
// unlike auto keyword, decltype will be affected with c-v qualifier.
160+
const int ci = 10;
161+
volatile int vi;
162+
decltype(ci) i1 = 1;
163+
bool same = std::is_same<decltype(i1), const int>::value;
164+
EXPECT_TRUE( same );
165+
same = std::is_same<decltype(i1), int>::value;
166+
EXPECT_FALSE( same );
167+
EXPECT_TRUE( std::is_const<decltype(i1)>::value );
168+
169+
decltype(vi) i2;
170+
same = std::is_same<decltype(i2), volatile int>::value;
171+
EXPECT_TRUE( same );
172+
EXPECT_TRUE( std::is_volatile<decltype(i2)>::value );
173173

174174
}
175175

176-
TEST(Decltype, IgnoreRepeatSpecifier) {
177-
int i = 1;
178-
int & ri = i;
179-
int * p = &i;
180-
const int k = 1;
181-
182-
decltype(i) ii = 1; // ii : int.
183-
EXPECT_EQ(typeid(ii).hash_code(), typeid(int).hash_code());
184-
// or
185-
bool same = std::is_same<int, decltype(ii)>::value;
186-
EXPECT_TRUE(same);
187-
188-
// ri2 will be int&. NOT int&& !
189-
// '&' before ri2 is ignore, decltype(ri) is already int&.
190-
decltype(ri) & ri2 = i;
191-
EXPECT_EQ(1, std::is_lvalue_reference<decltype(ri2)>::value);
192-
EXPECT_EQ(0, std::is_rvalue_reference<decltype(ri2)>::value);
193-
194-
decltype(p) ptri = &i; // ptri is int*.
195-
//decltype(p) * pptri = &i; // error: * will not be ignored. unlike &.
196-
decltype(p) * pptri = &p; // pptri is int**.
197-
same = std::is_same<int*, decltype(ptri)>::value;
198-
EXPECT_TRUE(same);
199-
same = std::is_same<int**, decltype(pptri)>::value;
200-
EXPECT_TRUE(same);
201-
202-
const decltype(k) ck = 10; // ck is const int. begenning 'const' is ignored.
203-
same = std::is_same<const int, decltype(ck)>::value;
204-
EXPECT_TRUE(same);
176+
TEST( Decltype, IgnoreRepeatSpecifier ) {
177+
int i = 1;
178+
int & ri = i;
179+
int * p = &i;
180+
const int k = 1;
181+
182+
decltype(i) ii = 1; // ii : int.
183+
EXPECT_EQ( typeid(ii).hash_code(), typeid(int).hash_code() );
184+
// or
185+
bool same = std::is_same<int, decltype(ii)>::value;
186+
EXPECT_TRUE( same );
187+
188+
// ri2 will be int&. NOT int&& !
189+
// '&' before ri2 is ignore, decltype(ri) is already int&.
190+
decltype(ri) & ri2 = i;
191+
EXPECT_TRUE( std::is_lvalue_reference<decltype(ri2)>::value );
192+
EXPECT_FALSE( std::is_rvalue_reference<decltype(ri2)>::value );
193+
194+
decltype(p) ptri = &i; // ptri is int*.
195+
//decltype(p) * pptri = &i; // error: * will not be ignored. unlike &.
196+
decltype(p) * pptri = &p; // pptri is int**.
197+
same = std::is_same<int*, decltype(ptri)>::value;
198+
EXPECT_TRUE( same );
199+
same = std::is_same<int**, decltype(pptri)>::value;
200+
EXPECT_TRUE( same );
201+
202+
const decltype(k) ck = 10; // ck is const int. begenning 'const' is ignored.
203+
same = std::is_same<const int, decltype(ck)>::value;
204+
EXPECT_TRUE( same );
205205
}
206206

207-
NS_END(decltype_test)
208-
NS_END(elloop)
207+
NS_END( decltype_test )
208+
NS_END( elloop )

understanding-c++11/trailing_return_type.cpp

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,27 @@ TEST(TrailingReturnType, UsedInTemplate) {
1515
}
1616

1717
TEST(TrailingReturnType, UsefulTest) {
18-
//todo test.
19-
//bool same = std::is_same<decltype(pf), decltype(pf1)>::value;
20-
//EXPECT_TRUE(same);
18+
/*
19+
int( *(*pf())() )() {
20+
return nullptr;
21+
}
22+
23+
auto pf1() -> auto (*)() -> int(*)() {
24+
return nullptr;
25+
}
26+
*/
27+
bool same = std::is_same<decltype(pf), decltype(pf1)>::value;
28+
EXPECT_TRUE(same);
29+
30+
typedef int( *ptr_f )();
31+
typedef ptr_f( *t )();
32+
same = std::is_same<t, decltype(pf())>::value;
33+
EXPECT_TRUE( same );
34+
35+
//ptr_f ptrf;
36+
//t ptr_ptr_f;
37+
//int( *ptr1 )() = ptrf;
38+
//int( *(*pptr1)() )() = ptr_ptr_f;
2139
}
2240
NS_END(trailing_return_type)
2341
NS_END(elloop)

understanding-c++11/trailing_return_type.h

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,24 @@ auto foo() -> int {
4444
auto foo2() -> void {}
4545

4646
// 2. function pointer
47-
//a complex declaration.
48-
int (*(*pf)())();
47+
//a complex function definition.
48+
// pf() defines a function, whose
49+
// return type A is a function ptr pA( pA = B (*pA)() ),
50+
// pA points to a type B, which is still a function ptr ( B = int (*)() ).
51+
int( *(*pf())() )() {
52+
return nullptr;
53+
}
4954

5055
// same with:
51-
auto (*pf1)() -> auto (*)() -> int(*)();
56+
auto pf1() -> auto (*)() -> int(*)() {
57+
return nullptr;
58+
}
59+
60+
61+
int ( *pf2() )() {
62+
return nullptr;
63+
}
64+
5265

5366
// 3. struct, union, enum. todo!
5467

0 commit comments

Comments
 (0)