本专栏目的
- 更新C/C++的基础语法,包括C++的一些新特性
前言
- 模板与元编程是C++的重要特点,也是难点,本人预计将会更新10期左右进行讲解,这是第六期,讲解元编程三种编程方式,这一部分小编感觉很难,我也是用了AI才学懂一点;
- 在元编程中,一般以类型为基础,不直接定义函数,定义函数也是在类中定义的;
- 后面一段时间暂时停止更新元编程,后面更新元编程内容结合STL,难度比较大,资料也少;
- C语言后面也会继续更新知识点,如内联汇编;
- 欢迎收藏 + 关注,本人将会持续更新。
C/C++语言基础–C++模板与元编程系列一(泛型、模板、函数模板、全特化函数模板………)
C/C++语言基础–C++模板与元编程系列二类模板、全特化、偏特化、编译模型简介、实现简单Vetctor等…………)
C/C++语言基础–C++模板与元编程系列三(变量模板、constexpr、萃取等…………)
C/C++语言基础–C++模板与元编程系列四(类型模板参数、整数、指针 、模板类型)
C/C++语言基础–C++模板与元编程系列五(可变惨模板,形参包展开,折叠表达式)
C/C++语言基础–C++模板与元编程系列六,C++元编程相关库的讲解与使用
顺序结构
🌇 顺序结构:这个说白了就是从上倒下依次执行。
🛍 案例:
- 用
using
自定义类型,定义一个类型,可以去除引用和cosnt属性
#include <iostream>
#include <type_traits>
using namespace std;
template <typename T>
struct Fun {
using RmRef = remove_reference<T>::type; // 去除引用
using type = remove_const<RmRef>::type; // 去除const属性
};
int main()
{
Fun<int&>::type x = 3;
Fun<const int&>::type y = 10;
y += 10;
cout << "x: " << x << "\ty: " << y << endl;
return 0;
}
⭕️ 输出:
选择结构
🙊 这个其实和我们正常的编程顺序if-else
一样,不一样的只是代码方式不同。
🐅注意:元编程传递数据,结合模板特化与偏特化,在<>中传递。
基于if constexpr
#include <iostream>
#include <type_traits>
using namespace std;
template <int num>
constexpr void judge()
{
if constexpr (num > 10) {
cout << num * 2 << endl;
}
else {
cout << num / 2 << endl;
}
}
int main()
{
judge<20>();
judge<8>();
return 0;
}
⭕️ 输出:
基于特化
这个就是结合模板的特化知识点
#include <iostream>
#include <type_traits>
using namespace std;
template<int x>
struct Img
{
constexpr static int y = x * 2;
};
// 特化
template<>
struct Img<100>
{
constexpr static int y = 100 - 10;
};
int main()
{
cout << Img<50>::y << endl;
cout << Img<100>::y << endl;
return 0;
}
⭕️ 输出:
基于requires
requires
是一个判断约束的条件,其实和if constexpr-else意思一样的,代码案例如下:
#include <iostream>
#include <type_traits>
using namespace std;
template <int x, int y>
requires(x >= 100 && y >= 50)
constexpr int add()
{
return x + y;
}
template <int x>
requires(x >= 100)
struct Img
{
constexpr static int value = x * 2;
};
int main()
{
constexpr int result = add<100, 200>(); // 一般在<> 中添加参数
cout << result << endl;
return 0;
}
基于enable_if
这个也是一个语法结构,注意这个可能需要结合,模板特化,模板特化主要是要抓住主模板、附模板的区别,
代码案例如下:
#include <iostream>
#include <type_traits>
using namespace std;
// 主模板
template<int x, typename = void>
struct Imp;
// x > 100 执行
template<int x>
struct Imp <x, enable_if_t<(x > 100)>>
{
constexpr static int y = x / 2;
};
// x <= 100 执行
template<int x>
struct Imp <x, enable_if_t<(x <= 100)>>
{
constexpr static int y = x * 2;
};
int main()
{
cout << Imp<100>::y << endl;
cout << Imp<50>::y << endl;
return 0;
}
⭕️ 输出:
注意:template<int x, enable_if_t<(x <= 100)>>
这种写法是不合法的,因为 enable_if_t
需要作为一个类型的别名,而不能直接作为模板参数列表的一部分。
循环结构
简介
🤗 循环结构一般结构递归实现,不用while、for
这样的循环,以类为对象(struct、class),不直接定义函数
👼 实现一个斐波那契数列计算:
#include <iostream>
#include <type_traits>
using namespace std;
// 定义主模板
template <int N>
struct fibonacci;
// 定义特化模板
template <>
struct fibonacci<0>
{
constexpr static int value = 0;
};
// 定义特化
template <>
struct fibonacci<1>
{
constexpr static int value = 1;
};
// 定义主训练
template <int N>
struct fibonacci
{
constexpr static int value = fibonacci<N - 1>::value + fibonacci<N - 2>::value;
};
int main()
{
cout << fibonacci<10>::value << endl;
return 0;
}
实现数组打印
😢😢😢,用了辅助工具AI才写出来,感觉太难了,😿😿😿😿
数组存储: 用可变参 + 类;
打印:采用模板特化实现,首先定义一个主模板,后定义要打印的特化模板,注意要定义一个只有一个参数打印的方法。
#include <iostream>
#include <utility>
#include <type_traits>
using namespace std;
// 定义数组
template <unsigned ...Args>
class Arr;
// 主模板
template <typename T>
struct print
{
};
// 模板特化
template <unsigned t, unsigned ...Args>
struct print<Arr<t, Args...>> // 特化语法,但是注意,主模板不允许这样使用
{
inline static void func()
{
cout << t << " ";
print<Arr<Args...>>::func(); // 递归
}
};
// 特化模板
template <>
struct print<Arr<>>
{
inline static void func()
{
}
};
int main()
{
using Array = Arr<1, 2, 3>;
print<Array>::func();
return 0;
}