support bazel complie this project and format code.
This commit is contained in:
38
cpp2.0/cpp11/variadic/BUILD
Normal file
38
cpp2.0/cpp11/variadic/BUILD
Normal file
@@ -0,0 +1,38 @@
|
||||
# please run `bazel run //cpp2.0/cpp11:variadic7`
|
||||
# please run `bazel run //cpp2.0/cpp11:variadic3_4`
|
||||
# please run `bazel run //cpp2.0/cpp11:variadic2`
|
||||
# please run `bazel run //cpp2.0/cpp11:variadic6`
|
||||
# please run `bazel run //cpp2.0/cpp11:variadic5`
|
||||
# please run `bazel run //cpp2.0/cpp11:variadic`
|
||||
# please run `bazel run //cpp2.0/cpp11:variadic1`
|
||||
|
||||
load("@rules_cc//cc:defs.bzl", "cc_binary")
|
||||
|
||||
cc_binary(
|
||||
name = "variadic7",
|
||||
srcs = ["variadic7.cpp"],
|
||||
)
|
||||
cc_binary(
|
||||
name = "variadic3_4",
|
||||
srcs = ["variadic3_4.cpp"],
|
||||
)
|
||||
cc_binary(
|
||||
name = "variadic2",
|
||||
srcs = ["variadic2.cpp"],
|
||||
)
|
||||
cc_binary(
|
||||
name = "variadic6",
|
||||
srcs = ["variadic6.cpp"],
|
||||
)
|
||||
cc_binary(
|
||||
name = "variadic5",
|
||||
srcs = ["variadic5.cpp"],
|
||||
)
|
||||
cc_binary(
|
||||
name = "variadic",
|
||||
srcs = ["variadic.cpp"],
|
||||
)
|
||||
cc_binary(
|
||||
name = "variadic1",
|
||||
srcs = ["variadic1.cpp"],
|
||||
)
|
66
cpp2.0/cpp11/variadic/variadic.cpp
Normal file
66
cpp2.0/cpp11/variadic/variadic.cpp
Normal file
@@ -0,0 +1,66 @@
|
||||
//
|
||||
// Created by light on 19-11-2.
|
||||
//
|
||||
|
||||
// variadic template(c++11) 数量不定的模板参数
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <tuple>
|
||||
|
||||
using namespace std;
|
||||
// 参数个数 参数个数逐一递减
|
||||
// 参数类型 参数类型也逐一递减
|
||||
|
||||
// (3)
|
||||
// 需要重载一个终止函数
|
||||
template<typename T>
|
||||
void _hash(size_t &seed, const T &val) {
|
||||
cout << "hash over " << val << endl;
|
||||
}
|
||||
|
||||
// (2)
|
||||
// 展开函数, 把参数分为一个普通参数和一个参数包,调用一次,参数包大小就减一
|
||||
template<typename T,typename... Args>
|
||||
void _hash(size_t &seed, const T& val,const Args &... args) {
|
||||
cout << "parameter " << val<< endl;
|
||||
// 递归调用自己
|
||||
_hash(seed, args...); // 上面如果不给T参数,会自己调用自己成死循环
|
||||
}
|
||||
|
||||
|
||||
// 泛化版 (1)
|
||||
template<typename ...Args>
|
||||
size_t _hash(const Args &... args) {
|
||||
cout << "hash start " << endl;
|
||||
size_t seed = 10;
|
||||
// 递归调用自己
|
||||
_hash(seed, args...);
|
||||
return seed;
|
||||
}
|
||||
|
||||
|
||||
template<typename ...Args>
|
||||
class A {
|
||||
private:
|
||||
int size = 0; // c++11 支持类内初始化
|
||||
public:
|
||||
A() {
|
||||
size = sizeof...(Args);
|
||||
cout << size << endl;
|
||||
}
|
||||
};
|
||||
|
||||
int main(void) {
|
||||
size_t f = 10;
|
||||
_hash("asdas", 2, 3, 4);
|
||||
A<int, string, vector<int>> a; // 类型任意
|
||||
|
||||
// Tuple就是利用这个特性(变长参数模板)
|
||||
tuple<int, string> t = make_tuple(1, "hha");
|
||||
int firstArg = get<0>(t);
|
||||
string secondArg = get<1>(t);
|
||||
cout << firstArg << " " << secondArg << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
32
cpp2.0/cpp11/variadic/variadic1.cpp
Normal file
32
cpp2.0/cpp11/variadic/variadic1.cpp
Normal file
@@ -0,0 +1,32 @@
|
||||
//
|
||||
// Created by light on 19-11-4.
|
||||
//
|
||||
|
||||
#include <iostream>
|
||||
#include <bitset>
|
||||
|
||||
using namespace std;
|
||||
|
||||
// example 1
|
||||
void printX() {
|
||||
|
||||
}
|
||||
|
||||
// 特化
|
||||
template<typename T, typename... Type>
|
||||
void printX(const T &firstArg, const Type &...args) {
|
||||
cout << firstArg << endl; // 先减少一个做操作
|
||||
printX(args...); // 其余的继续分为一个+一包进行递归知道没有了 调用printX()
|
||||
}
|
||||
|
||||
// 如果写了下面接收任意参数,下面这个跟上面可以共存 泛化版 永远不会被调用,前面特化把它取代了
|
||||
template<typename T, typename... Type>
|
||||
void printX(const Type &...args) {
|
||||
printX(args...);
|
||||
}
|
||||
|
||||
|
||||
int main() {
|
||||
printX(1, "hello", bitset<16>(377), 42);
|
||||
return 0;
|
||||
}
|
34
cpp2.0/cpp11/variadic/variadic2.cpp
Normal file
34
cpp2.0/cpp11/variadic/variadic2.cpp
Normal file
@@ -0,0 +1,34 @@
|
||||
//
|
||||
// Created by light on 19-11-4.
|
||||
//
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
void print(const char *s) {
|
||||
while (*s) {
|
||||
if (*s == '%' && *(++s) != '%')
|
||||
throw std::runtime_error("invalid format string: missing arguments");
|
||||
std::cout << *s++;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T, typename... Args>
|
||||
void print(const char *s, T value, Args... args) {
|
||||
while (*s) {
|
||||
if (*s == '%' && *(++s) != '%') {
|
||||
std::cout << value;
|
||||
print(++s, args...); // 即便当 *s == 0 也会产生调用,以检测更多的类型参数。
|
||||
return;
|
||||
}
|
||||
std::cout << *s++;
|
||||
}
|
||||
throw std::logic_error("extra arguments provided to printf");
|
||||
}
|
||||
|
||||
int main() {
|
||||
int *pi = new int;
|
||||
print("%d %s %p %f\n", 15, "Acc", pi, 3.14);
|
||||
return 0;
|
||||
}
|
31
cpp2.0/cpp11/variadic/variadic3_4.cpp
Normal file
31
cpp2.0/cpp11/variadic/variadic3_4.cpp
Normal file
@@ -0,0 +1,31 @@
|
||||
//
|
||||
// Created by light on 19-11-4.
|
||||
//
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
// 参数type相同的max
|
||||
int max(initializer_list<int> initializerList) {
|
||||
int res = *initializerList.begin();
|
||||
for (auto elem:initializerList)
|
||||
res = max(res, elem);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
// 参数type相同的maximum
|
||||
int maximum(int n) {
|
||||
return n;
|
||||
}
|
||||
|
||||
template<typename ...Args>
|
||||
int maximum(int n, Args...args) {
|
||||
return std::max(n, maximum(args...));
|
||||
}
|
||||
|
||||
int main() {
|
||||
cout << max({10, 8, 100, 1}) << endl;
|
||||
cout << maximum(57, 48, 60, 100, 20, 18) << endl;
|
||||
}
|
44
cpp2.0/cpp11/variadic/variadic5.cpp
Normal file
44
cpp2.0/cpp11/variadic/variadic5.cpp
Normal file
@@ -0,0 +1,44 @@
|
||||
//
|
||||
// Created by light on 19-11-4.
|
||||
//
|
||||
|
||||
#include <iostream>
|
||||
#include <tuple>
|
||||
#include <bitset>
|
||||
|
||||
using namespace std;
|
||||
|
||||
// tuple递归调用
|
||||
|
||||
// 得出这种打印[7,5....,42]
|
||||
// 需要知道有几个以及现在操作的是第几个 sizeof...()
|
||||
|
||||
// cout<< make_tuple(7.5,string("hello"),bitset<16>(377),47);
|
||||
|
||||
|
||||
template<int IDX, int MAX, typename... Args>
|
||||
struct print_tuple {
|
||||
static void print(ostream &os, const tuple<Args...> &t) {
|
||||
os << get<IDX>(t) << (IDX + 1 == MAX ? "" : ",");
|
||||
print_tuple<IDX + 1, MAX, Args...>::print(os, t);
|
||||
}
|
||||
};
|
||||
|
||||
// 偏特化
|
||||
template<int MAX, typename... Args>
|
||||
struct print_tuple<MAX, MAX, Args...> {
|
||||
static void print(ostream &os, const tuple<Args...> &t) {
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ... Args>
|
||||
ostream &operator<<(ostream &os, const tuple<Args...> &t) {
|
||||
os << "[";
|
||||
print_tuple<0, sizeof...(Args), Args...>::print(os, t);
|
||||
return os << "]";
|
||||
}
|
||||
|
||||
|
||||
int main() {
|
||||
cout << make_tuple(7.5, string("hello"), bitset<16>(377), 47) << endl;
|
||||
}
|
52
cpp2.0/cpp11/variadic/variadic6.cpp
Normal file
52
cpp2.0/cpp11/variadic/variadic6.cpp
Normal file
@@ -0,0 +1,52 @@
|
||||
//
|
||||
// Created by light on 19-11-4.
|
||||
//
|
||||
|
||||
#include <iostream>
|
||||
|
||||
|
||||
using namespace std;
|
||||
// 上一个例子:variadic5.cpp为递归调用
|
||||
// 当前这个例子为递归继承
|
||||
namespace light {
|
||||
template<typename...Values>
|
||||
class tuple;
|
||||
|
||||
template<>
|
||||
class tuple<> {
|
||||
};
|
||||
|
||||
template<typename Head, typename...Tail>
|
||||
class tuple<Head, Tail...> : private tuple<Tail...> {
|
||||
typedef tuple<Tail...> inherited;
|
||||
protected:
|
||||
Head m_head;
|
||||
public:
|
||||
tuple() {}
|
||||
|
||||
tuple(Head h, Tail...tail) : m_head(h), inherited(tail...) {}
|
||||
|
||||
// decltype()中的m_head必须放到前面,否则编译器找不到
|
||||
auto head() -> decltype(m_head) { return m_head; }
|
||||
// 或者 Head head() { return m_head; }
|
||||
|
||||
inherited &tail() { return *this; }
|
||||
};
|
||||
}
|
||||
/**
|
||||
* string 32 8字节对齐
|
||||
* float 4
|
||||
* int 4
|
||||
* 4+4+32=40 自底向上
|
||||
*/
|
||||
|
||||
int main() {
|
||||
using light::tuple;
|
||||
tuple<int, float, string> t(41, 6.3, "nico");
|
||||
cout << sizeof(t) << endl;
|
||||
cout << t.head() << endl;
|
||||
cout << t.tail().head() << endl;
|
||||
cout << t.tail().tail().head() << endl;
|
||||
|
||||
return 0;
|
||||
}
|
57
cpp2.0/cpp11/variadic/variadic7.cpp
Normal file
57
cpp2.0/cpp11/variadic/variadic7.cpp
Normal file
@@ -0,0 +1,57 @@
|
||||
//
|
||||
// Created by light on 19-11-4.
|
||||
//
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace light {
|
||||
template<typename...Values>
|
||||
class tuple;
|
||||
|
||||
template<>
|
||||
class tuple<> {
|
||||
};
|
||||
|
||||
template<typename Head, typename...Tail>
|
||||
class tuple<Head, Tail...> {
|
||||
typedef tuple<Tail...> composited;
|
||||
protected:
|
||||
Head m_head;
|
||||
composited m_tai;
|
||||
public:
|
||||
tuple() {}
|
||||
int get() { return sizeof(composited);}
|
||||
tuple(Head h, Tail...tail) : m_head(h), m_tai(tail...) {}
|
||||
|
||||
// decltype()中的m_head必须放到前面,否则编译器找不到
|
||||
auto head() -> decltype(m_head) { return m_head; }
|
||||
// 或者 Head head() { return m_head; }
|
||||
|
||||
composited &tail() { return m_tai; }
|
||||
};
|
||||
}
|
||||
|
||||
// 根据string为8字节对齐,我们得出8字节对齐
|
||||
// 第一次 int 4字节Head调整到边界8 那composite呢?继续往下分析
|
||||
// 第二次 把第一次的composited拆分为float与一包, float也占4字节,调整到8边界为8字节,那这一步的composited呢?继续往下分析
|
||||
// 第三次 把第二次的compoisted拆分成sting与一包, string占32字节,已经为8倍数,无需调整,而这一步的composited呢?由于到这里一包已经没了,就会调用它的全特化版本,全特环版本为空,sizeof为1,
|
||||
// 调整到8的倍数为8.
|
||||
// 因此最后的内存结构(自底向上)为:8 + 8 + 32 + 8 = 56 64位机器结果
|
||||
|
||||
struct A {
|
||||
string a;
|
||||
float b;
|
||||
};
|
||||
int main() {
|
||||
using light::tuple;
|
||||
tuple<int, float, string> t(41, 6.3, "nico");
|
||||
cout<<sizeof(A)<<endl;
|
||||
cout<<t.get()<<endl;
|
||||
cout << sizeof(t) << endl;
|
||||
cout << t.head() << endl;
|
||||
cout << t.tail().head() << endl;
|
||||
cout << t.tail().tail().head() << endl;
|
||||
return 0;
|
||||
}
|
Reference in New Issue
Block a user