逗号运算符(非常重要)
逗号运算符规则:
表达式1, 表达式2
// 计算表达式1(但丢弃结果)
// 返回表达式2 的值和类型
int x = (42, 100); // x = 100(丢弃42)
decltype(42, 100) // 推导为 int(100的类型)也就是说,逗号运算符返回的只与最后一个表达式下相关
应用示例:在编译期检测是否还有某个方法
// SIFINAE技术:用于在编译期检测类型是否具有特定方法
template <typename F, typename... Args> class has_compute {
private:
template <typename U>
// 注意增加参数是必须的,目的是为了区分重载,否则会和下面的test(...)冲突,优先级更高
static auto test(bool) -> decltype(std::declval<U>().compute(std::declval<Args>()...), std::true_type{});
template <typename> static std::false_type test(...);
public:
static constexpr bool value = decltype(test<F>(true))::value;
};
应用示例:通用的检测是否有某个方法
// SIFINAE技术:用于在编译期检测类型是否具有特定方法
#define HAS_METHOD(method_name) \
template <typename T, typename... Args> class has_##method_name { \
private: \
template <typename U> \
static auto test(int) -> decltype(std::declval<U>().method_name(std::declval<Args>()...), std::true_type{}); \
\
template <typename> static std::false_type test(...); \
\
public: \
static constexpr bool value = decltype(test<T>(0))::value; \
};
HAS_METHOD(compute) // 检测是否有 compute 方法C++20格式化字符串
总结:
- 使用只读的std::string_view来读取字符串,提高效率
- 使用20的格式化字符串功能:std::vformat
- 对可变参数进行字符串格式化:std::make_format_args
需要深入理解的点:
- 格式化的规则都有哪些,如{},其它规则都是什么?
- 可变参数如何解析?除了递归调用,有没有其它方法
std::string msg = "123{},{}";
std::string_view fmt(msg); //只读的字符串视图,主要是保存字符的index等信息,无法修改
template <typename... T>
void debug(std::string_view fmt,T&&... arg)
{
const auto& msg = std::vformat(fmt, std::make_format_args(arg...));
//c++20的格式化字符串
}
C++20 requires关键字
可变参数的展开(##VA_ARGS)
使用##VA_ARGS来对可变参数进行扩展,展开,使用语法:
- 定义:预处理宏
- 作用:结合…来使用,是对它的解包
- 说明:使用前面的##主要的原因在于,防止可变参数为空时报错
using给函数对象声明类型别名,支持函数调用异步调用场景
- 定义:
using FuncCb = std::function<void(double)> - 作用:声明函数对象的类型别名,可以将函数对象参数化
- 示例:
using FuncCb = std::function<void(double,const std::string&)>;
struct RunCb
{
void setCb(const FuncCb cb)
{
_cb = cb;
}
FuncCb getCb()
{
return _cb;
}
FuncCb _cb;
};
void cb1(double val,const std::string& str)
{
cout<<"cb1 "<<val<<" name:"<<str<<endl;
}
void cb2(double val,const std::string& str)
{
cout<<"cb2 "<<val<<" name:"<<str<<endl;
}
int main()
{
RunCb cb;
cb.setCb(cb1);
auto fun = cb.getCb();
fun(21.1,"hello");
cb.setCb(cb2);
fun = cb.getCb();
fun(21.1,"hello");
return 0;
}使用模版的模版参数
#pragma once
#include <deque>
//模板的模板参数只能用在类模板、成员函数中,无法应用于函数模板中
template<typename T,template<typename ELEM,typename ALLOC = std::allocator<ELEM>> class CONT = std::deque>
class Stack{
public:
void push(T const& value)
{
elems.push_front(value);
}
void pop()
{
elems.pop_front();
}
T top() const
{
return elems.front();
}
bool empty() const{
return elems.empty();
}
template<typename T2,template<typename,typename> class CONT2>
Stack<T,CONT>& operator=(Stack<T2,CONT2> const& stack)
{
if((void*)this == (void*)& stack)
return *this;
Stack<T2,CONT2> tmp(stack);
elems.clear();
while (!tmp.empty())
{
elems.push_front(tmp.top());
tmp.pop();
}
return *this;
}
private:
CONT<T> elems;
};std::is_same_v的底层实现
std::is_same_v是一个类型特征(type trait)工具,用于在编译期判断两个类型是否完全相同,属于严格判断
#include <type_traits>
// 基本用法
static_assert(std::is_same_v<int, int>); // true
static_assert(!std::is_same_v<int, float>); // true
static_assert(!std::is_same_v<int, const int>); // true (const修饰不同)主要的目的有以下几个点:
- 模板元编程中的类型检查
- SFINATE(替换失败不是错误)和概念约束
// 只允许 int 类型的函数
template<typename T>
std::enable_if_t<std::is_same_v<T, int>, void>
foo(T value) {
std::cout << "Only accepts int\n";
}- 静态断言保证类型安全
- 类型推导验证
核心实现如下(可运行版):
// 自定义实现std::is_same,使用模板元编程的方式
template <typename T, T v> struct integral_constant_cus {
static constexpr T value = v;
using value_type = T;
using type = integral_constant_cus; // using声明,方便模板元编程调用
constexpr operator value_type() const noexcept { return value; } // 转换为value_type类型
};
using true_type_cus = integral_constant_cus<bool, true>;
using false_type_cus = integral_constant_cus<bool, false>;
template <typename T, typename U> struct is_same_cus : false_type_cus {}; // 默认不相同
template <typename T> struct is_same_cus<T, T> : true_type_cus {}; // 特化相同
template <typename T, typename U> inline constexpr bool is_same_cus_v = is_same_cus<T, U>::value; // 方便使用的变量模板作者:admin 创建时间:2023-04-26 14:34
最后编辑:admin 更新时间:2025-10-10 17:51
最后编辑:admin 更新时间:2025-10-10 17:51