c++ move forward

lvalue: loactor value
rvalue: read value

here is an example of class definition with only one constructor using template and 'forward' technique to tackle varying parameter:

rvalue.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
#include <iostream>
#include <functional>
 
using namespace std;
 
template <typename T>
constexpr bool is_lvalue(T&) {
	return true;
}
 
template <typename T>
constexpr bool is_lvalue(T&&) {
	return false;
}
 
class MyStr
{
public:
	template<class T>
	MyStr(T&& t)
	{
		set(forward<T>(t));
	}
	template<class T>
	void set(T&& t)
	{
		if constexpr (conjunction_v<is_convertible<T&, MyStr&>>)
		{
			if (!is_lvalue(forward<T>(t)))
			{
				str_ = forward<string>(t.str_);
				cout << "is rvalue, type MyStr." << endl;
			}
			else
			{
				str_ = t.str_;
				cout << "is lvalue, type MyStr." << endl;
			}
		}
		else
		{
			str_ = forward<T>(t);
			cout << "is string." << endl;
		}
	}
	template<class T=char>
	void test()
	{
		cout << "test T size is " << sizeof(T) << endl;
	}
	string str_;
};
 
int main()
{
	cout << "call constructor:" << endl;
 
	MyStr str1("str1");
	MyStr str2(str1);
	MyStr str3(move(str1));
 
	cout << "call member function:" << endl;
 
	str1.set("set1");
	str2.set(str1);
	str3.set(move(str1));
 
	str3.test();
 
	return 1;
}

make

1
g++ -o rvalue -g -O0 -std=c++17 rvalue.cpp

output

1
2
3
4
5
6
7
8
call constructor:
is string.
is lvalue, type MyStr.
call member function:
is string.
is lvalue, type MyStr.
is rvalue, type MyStr.
test T size is 1

refer to:
http://www.javashuo.com/article/p-olwxiggw-q.html
http://c.biancheng.net/view/7829.html
https://zhuanlan.zhihu.com/p/99524127

c++虚继承

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
#include <iostream>
 
using namespace std;
 
class Base {
public:
	virtual ~Base() {}
	virtual void func() = 0;
	int base_;
};
 
class SubLeft : virtual public Base {
public:
	int subLeft_;
};
 
class SubRight : virtual public Base {
public:
	int subRight_;
};
 
class Diamond : public SubLeft, public SubRight {
public:
	void func() {}
	int diamond_;
};
 
int main()
{
	Diamond diamond;
	cout << "sizeof Base: " << sizeof(Base) << endl;
	cout << "sizeof SubLeft: " << sizeof(SubLeft) << endl;
	cout << "sizeof Diamond: " << sizeof(Diamond) << endl;
	cout << "base_ offset: " << (size_t)&diamond.base_ - (size_t)&diamond << endl;
	cout << "subLeft_ offset: " << (size_t)&diamond.subLeft_ - (size_t)&diamond << endl;
	return 1;
}

编译环境是vs2019 x64,项目属性 => C/C++ => Command Line中增加

1
/d1reportSingleClassLayoutDiamond

编译时输出

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
1>class SubLeft	size(32):
1>	+---
1> 0	| {vbptr}
1> 8	| subLeft_
1>  	| <alignment member> (size=4)
1>	+---
1>	+--- (virtual base Base)
1>16	| {vfptr}
1>24	| base_
1>  	| <alignment member> (size=4)
1>	+---
1>class Diamond	size(56):
1>	+---
1> 0	| +--- (base class SubLeft)
1> 0	| | {vbptr}
1> 8	| | subLeft_
1>  	| | <alignment member> (size=4)
1>	| +---
1>16	| +--- (base class SubRight)
1>16	| | {vbptr}
1>24	| | subRight_
1>  	| | <alignment member> (size=4)
1>	| +---
1>32	| diamond_
1>  	| <alignment member> (size=4)
1>	+---
1>	+--- (virtual base Base)
1>40	| {vfptr}
1>48	| base_
1>  	| <alignment member> (size=4)
1>	+---
1>Diamond::$vbtable@SubLeft@:
1> 0	| 0
1> 1	| 40 (Diamondd(SubLeft+0)Base)
1>Diamond::$vbtable@SubRight@:
1> 0	| 0
1> 1	| 24 (Diamondd(SubRight+0)Base)
1>Diamond::$vftable@:
1>	| -40
1> 0	| &Diamond::{dtor}
1> 1	| &Diamond::func
1>Diamond::func this adjustor: 40
1>Diamond::{dtor} this adjustor: 40
1>Diamond::__delDtor this adjustor: 40
1>Diamond::__vecDelDtor this adjustor: 40
1>vbi:	   class  offset o.vbptr  o.vbte fVtorDisp
1>            Base      40       0       4 0

运行输出

1
2
3
4
5
sizeof Base: 16
sizeof SubLeft: 32
sizeof Diamond: 56
base_ offset: 48
subLeft_ offset: 8

refer to: https://blog.csdn.net/oracleot/article/details/5123657

euhat-language-v0.7.0.8

Euhat language is very similar to C language, but she does not need to compile first, she can directly run.

Euhat language can directly call windows api or dll api.

The entrance code file must have a "main" function, and it should include all relative code files through include instruction. so this method allows us run all the code files without writing makefile.

Definition is composed of function definition, structure definition, normal variable definition and func variable definition. The default accessability of definition in a code file is accessable among all code files. If you want definition not shared by other code files, you need to add "static" keyword in front of the definition statement.

An entrance code file and its relative code files construct a program, you can compile a program into a binary file which you can protect your right for un-disassembling, through compilation, you will find a syms file generated, which contains meaningful variable name to non-meaningful variable name projection, you can use it debug you program, and keep it secret not publishing.

Download link: euhat-language-v0.7.0.8.zip

Backup link: http://pan.baidu.com/s/1sj19Inb

Backup link: http://1drv.ms/1vic9DB