格式化指针
int main() {auto i = 42;std::cout << std::format("{:#018X}", reinterpret_cast<uintptr_t>(&i)); // prints 0X00007FFD9D71776C
}
格式化串指针
"std.format ptr"_test = [] {auto ptr = reinterpret_cast<std::uintptr_t>(nullptr);expect("0"sv == std::format("{:#0}", ptr));expect("000000000000000000"sv == std::format("{:#018}", ptr));expect("0x0000000000000000"sv == std::format("{:#018x}", ptr));expect("0X0000000000000000"sv == std::format("{:#018X}", ptr));
};
无名占位符
auto foo() { return 42; }int main() {auto unused = foo(); // warning in C++23auto _ = foo(); // no warning in C++26
}
用户生成静断
static_assert(false, std::string_view{"message"});
加静断格式
template<auto... Cs>
constexpr auto format(const string<Cs...> fmt, auto&&... args) {std::array<char, sizeof...(Cs)> a{};for (auto i = 0; i < sizeof...(Cs); ++i) {if (fmt.str[i] == '{' and fmt.str[i+1] == '}') {a[i] = '0'+(args,...);a[++i] = ' ';} else {a[i] = fmt.str[i];}}return a;
};struct foo {};
static_assert(sizeof(foo) == 0, format("Unexpected sizeof: expected 0, got {}"_s, sizeof(foo)));
绑定前
struct foo {auto bar(int v) { return v; }
};static_assert(42 == std::bind_front<&foo::bar>(foo{}, 42));
// TODO bind_frontstruct foo {constexpr auto bar(int n) const { return n; }
};int main() {constexpr auto f = foo{};constexpr auto fn = bind_front<&foo::bar>(f);static_assert(42 == fn(42));
}
实现:
template<auto Fn>
[[nodiscard]] constexpr auto bind_front(auto&& obj,auto&&...bound_args) {return [=](auto&&...args){return (obj.*Fn)(bound_args..., args...);};
}
基本字符集,加了$@与反引
auto $dollar_sign = 42;
auto @commerical_at = 42;
auto `grave_accent = 42;
// math
auto a = 42;
auto a` = a*2;// macros
$macro(...) ```// twitter
auto id = @kris;
运行时分发
template <template <class...> class TList, class TEvent, class... TEvents, class T, class TExpr>
constexpr auto dispatch(TList<TEvent, TEvents...>, const int id, const T& data,const TExpr& expr) -> decltype(expr(TEvent{data})) {switch (id) {case TEvent::id:return expr(TEvent{data});default:if constexpr (sizeof...(TEvents) > 0) {return dispatch(TList<TEvents...>{}, id, data, expr);}}return {};
}
template <template <class...> class TList, class TEvent, class... TEvents,class T, class TExpr>
constexpr auto dispatch(TList<TEvent, TEvents...>, const int id, const T& data,const TExpr& expr) -> decltype(expr(TEvent{data})) {// if elseif (id == TEvent::id) {return expr(TEvent{data});} else if constexpr (sizeof...(TEvents) > 0) {return dispatch(TList<TEvents...>{}, id, data, expr);}return 0;
}
template <class... TEvents, class T, class TExpr>
constexpr auto dispatch(const int id, const T& data, const TExpr& expr) {// jump tableconst auto jump_table = [expr](TEvents... events) {return std::array{(expr(events))...};}(TEvents{data}...);return jump_table[id];
}
template <class... TEvents, class T, class TExpr>
constexpr auto dispatch(const int id, const T& data, const TExpr& expr) {// fold expressionsreturn ([&](auto&& event) {if (id == event.id) {return expr(event);}return 0;}(TEvents{data}) + ...);
}
调用r
#include <functional>constexpr auto sum(auto... ts) { return (ts + ...); }
static_assert(typeid(int) == typeid(std::invoke_r<int>(&sum<short, short>, 3, 4)));
[[nodiscard]] constexpr auto call(auto... ts) {using Ret = std::common_type_t<decltype(ts)...>;return std::invoke_r<Ret>(sum<decltype(ts)...>, ts...);
}
[[nodiscard]] constexpr auto call(auto... ts){using T = typename std::common_type_t<decltype(ts)...>;return std::invoke_r<T>(&sum<decltype(ts)...>, ts...);
}
编译时跳转表
template <auto N = 42>
constexpr auto dispatch(auto n) -> int {using foo_return_type = std::invoke_result<decltype(&foo<0>)>::type;const auto jump_table = []<auto... I>(std::index_sequence<I...>) {return std::array<foo_return_type, sizeof...(I)>{(foo<I>())...};}(std::make_index_sequence<N>{});return jump_table[n];
};
C++虚继承
template <class... Ts>
struct interface {public:template <class T>const T& on(T) const {return std::get<T>(vs);}protected:constexpr explicit interface(auto&&... args) : vs(args...) {}private:std::tuple<Ts...> vs;
};template <auto... Vs>
struct implementation final : interface<decltype(Vs)...> {constexpr explicit implementation() : interface<decltype(Vs)...>(Vs...) {}
};
template <class... Ts>
struct interface : virtual interface<Ts>... {using interface<Ts>::on...;
};template <class T>
struct interface<T> {virtual T on(T) const = 0;virtual ~interface() noexcept = default;
};template <auto... Vs>
struct implementation : interface<decltype(Vs)...>, implementation<Vs>... {};template <auto V>
struct implementation<V> : virtual interface<decltype(V)> {using T = decltype(V);T on(T) const { return V; }
};
template <class... Ts>
struct interface : virtual interface<Ts>... {using interface<Ts>::on...;
};template <class T>
struct interface<T> {virtual T on(T) const = 0;
};template <auto... Vs>
struct implementation final : implementation<Vs>..., interface<decltype(Vs)...> {};template <auto V>
struct implementation<V> : virtual interface<decltype(V)> {using T = decltype(V);T on(T) const override { return V; }
};
C++传递概念
template<class T>
concept foo_like = requires(T t) { t.foo; };template<auto Concept>
struct foo {auto fn(auto f) {static_assert(requires { Concept(f); });}
};int main() {foo<[](foo_like auto){}> f{};struct { int foo{}; } foo;struct { } bar;f.fn(foo); // okf.fn(bar); // error: contrain not satisfied
}
所有构字段
[[nodiscard]] constexpr auto all_structs_field_names() {return []<auto... Is>(std::index_sequence<Is...>) {return std::apply([](auto... elements) {static_vector<std::string_view, sizeof...(elements)> v{};(..., v.push_back(elements.name));return v;},std::tuple_cat(to_tuple(typeof<[] { return meta_find<"struct">[Is]; }>{})...));}(std::make_index_sequence<meta_find<"struct">.size()>{});
}
成员到名字
[[nodiscard]] constexpr auto members_to_names(auto& out, auto struct_members) {constexpr auto num_members = std::tuple_size_v<decltype(struct_members)>;[&out, &struct_members]<auto... Ns>(std::index_sequence<Ns...>) {(out.push_back(std::get<Ns>(struct_members).name), ...);}(std::make_index_sequence<num_members>{});
}template
<std::size_t index>
[[nodiscard]] constexpr auto struct_instance() {return typeof<[] { return structs[index]; }>{};
};template
<std::size_t MaxSize = 8>
[[nodiscard]] constexpr auto all_structs_field_names() {static_vector<std::string_view, MaxSize> names{};[&names]<auto... Ns>(std::index_sequence<Ns...> ns) {(members_to_names(names, to_tuple(struct_instance<Ns>())), ...);}(std::make_index_sequence<structs.size()>{});return names;
}
C++嵌入串
#include <string_view>static constexpr char self[] = {#embed __FILE__
};static_assert(std::string_view{std::cbegin(self), std::cend(self)}.front() == '#');
static_assert(std::string_view{std::cbegin(self), std::cend(self)}.back() == ';');
常式向量
template<auto... Ns> consteval auto fn() {std::vector v{Ns...};return std::size(v);
}static_assert(3uz == fn<1, 2, 3>());
静常式
constexpr auto foo() {static constexpr auto value = 42; // error in C++20, okay in C++23return value;
}
常式串
#include <string>constexpr auto foo() {return std::string{"bar"};
}static_assert("bar" == foo());
[[nodiscard]] constexpr auto concat(auto... args) {return (args() + ... + ""s);
}
结构绑定
struct foo {int i{};std::string s{};
};template <auto N>
const auto& get(const foo& f) {if constexpr (N == 0) {return f.i;} else if constexpr (N == 1) {return f.s;}
}namespace std {
template <>
struct tuple_size<::foo> : integral_constant<std::size_t, 2> {};template <std::size_t N>
struct tuple_element<N, ::foo> {using type = decltype(get<N>(std::declval<::foo&>()));
};
} // namespace stdint main() {auto [i, s] = foo{.i = 42, .s = "str"};assert(42 == i);assert("str" == s);
}
auto [... Is] = std::make_index_sequence<42>{};
static_assert(sizeof...(Is) == 42);
namespace std {template <std::size_t N>
using index_constant = std::integral_constant<std::size_t, N>;template <auto N, auto... Is>
auto get(index_sequence<Is...>) {return index_constant<N>{};
}template <auto... Is>
struct tuple_size<index_sequence<Is...>> : index_constant<sizeof...(Is)> {};template <auto N, auto... Is>
struct tuple_element<N, index_sequence<Is...>> {using type = index_constant<N>;
};} // namespace std
namespace std {template<auto N, size_t ...Ints>
auto constexpr get(const index_sequence<Ints...>&) {return get<N>(tuple{integral_constant<size_t, Ints>{}...});
};template<size_t ... Ints>
struct tuple_size<index_sequence<Ints...>> : integral_constant<size_t, sizeof...(Ints)> {};template<size_t N, size_t ...Ints>
struct tuple_element<N, index_sequence<Ints...>> {using type = decltype(get<N>(tuple{integral_constant<size_t, Ints>{}...}));
};
}
namespace stdext {template <std::size_t... Is>
struct index_sequence : std::index_sequence<Is...> {template <std::size_t I>auto get() const -> std::tuple_element_t<I, index_sequence> {return {};}
};namespace detail {template <std::size_t N, class = std::make_index_sequence<N>>
struct make_index_sequence;template <std::size_t N, auto... Is>
struct make_index_sequence<N, std::index_sequence<Is...>> {using type = index_sequence<Is...>;
};} // namespace detailtemplate <std::size_t N>
using make_index_sequence = typename detail::make_index_sequence<N>::type;} // namespace stdext