
c++ 常见宏、模板用法【1】
记录几个常见的好用的宏和模板编程技巧的示例,它们可以提高代码的可读性、可维护性和灵活性,为开发人员提供了更多的选择和工具来处理复杂的编程问题。
·
1、宏定义实现简单的断言
#define ASSERT(expr) \
if(!(expr)) { \
std::cout << "assertion failed: " << #expr << " at " << __FILE__ << ":" << __LINE__ << std::endl; \
abort(); \
}
该宏定义了一个简单的断言,如果表达式expr为false,则在标准错误流中输出错误消息,包括出错文件名和行号,并终止程序执行。
int main() {
ASSERT(0);
return 0;
}
输出
C:\Users\hanhandi\CLionProjects\untitled\cmake-build-debug\untitled.exe
assertion failed: 0 at C:/Users/hanhandi/CLionProjects/untitled/main.cpp:12
2、可变参数模板
template<typename T, typename... Args>
void print(T t, Args... args) {
std::cout << t << " ";
if constexpr (sizeof...(args) > 0)
print(args...);
}
该函数使用可变参数模板,可以接受任意数量的参数,并依次输出到标准输出流中。
int main() {
print("xx", "xxx", "xxxx");
return 0;
}
输出
xx xxx xxxx
3、变量模板
template<typename T>
constexpr T pi = T(3.1415926535897932385L);
该模板定义了一个常量pi,表示圆周率并具有指定的精度。
int main() {
char val = 0;
std::cout << pi<int> << std::endl;
std::cout << pi<float> << std::endl;
std::cout << pi<double> << std::endl;
std::cout << pi<long> << std::endl;
return 0;
}
输出
3
3.14159
3.14159
3
4、宏定义实现范围内的for循环
#define for_range(i, begin, end) \
for(auto i = begin; i < end; ++i)
该宏定义了一个基于循环变量和范围的for循环,避免了手动指定循环条件和步长的麻烦。
int main() {
int i = 0;
std::cout << i << std::endl;
for_range(i, 0, 2) {
std::cout << i << std::endl;
}
return 0;
}
输出
0
0
1
5、模板实现函数对象
template<typename T>
struct add_one {
T operator()(T val) const {
return val + 1;
}
};
该模板定义了一个函数对象,用于将输入值加1。
template<typename T>
struct add_one {
T operator()(T val) const {
return val + 1;
}
};
int main() {
int i = 0;
float f = 1.2;
std::cout << i << std::endl;
std::cout << f << std::endl;
add_one<int> addOneInt;
add_one<float> addOneFloat;
int res_i = addOneInt(i);
float res_f = addOneFloat(f);
std::cout << res_i << std::endl;
std::cout << res_f << std::endl;
return 0;
}
输出
0
1.2
1
2.2
6、宏定义实现作用域限定
#define UNIQUE_NAME(prefix) CONCAT(prefix, __COUNTER__)
#define CONCAT(a, b) INNER_CONCAT(a, b)
#define INNER_CONCAT(a, b) a ## b
class MyClass {
public:
void my_function() {
int UNIQUE_NAME(my_var) = 42;
// ...
}
};
该宏定义了一个唯一的名称,用于在指定作用域中声明临时变量。这些变量的名称由给定的前缀和一个自增计数器组成,可以确保在同一作用域内不会重复使用相同的名称。
#define UNIQUE_NAME(prefix) CONCAT(prefix, __COUNTER__)
#define CONCAT(a, b) INNER_CONCAT(a, b)
#define INNER_CONCAT(a, b) a ## b
class MyClass {
public:
void my_function() {
int UNIQUE_NAME(my_var) = 42;
int UNIQUE_NAME(my_var) = 43;
std::cout << my_var0 << std::endl;
std::cout << my_var1 << std::endl;
// ...
}
};
int main() {
MyClass myClass;
myClass.my_function();
return 0;
}
输出
42
43
7、类型萃取模板
template<typename T>
struct is_pointer {
static const bool value = false;
};
template<typename T>
struct is_pointer<T*> {
static const bool value = true;
};
该模板使用模板特化来判断给定类型是否为指针类型。
下面结合上面的宏定义实现作用域限定来写个demo:
#define UNIQUE_NAME(prefix) CONCAT(prefix, __COUNTER__)
#define CONCAT(a, b) INNER_CONCAT(a, b)
#define INNER_CONCAT(a, b) a ## b
template<typename T>
struct is_pointer {
static const bool value = false;
};
template<typename T>
struct is_pointer<T*> {
static const bool value = true;
};
int main() {
is_pointer<int*> UNIQUE_NAME(isPointer);
std::cout << isPointer0.value << std::endl;
is_pointer<int> UNIQUE_NAME(isPointer);
std::cout << isPointer1.value << std::endl;
return 0;
}
输出为
1
0
更多推荐
所有评论(0)