公开Base的内容
#include <iostream>
using namespace std;
struct Base
{
Base()
{container++;}
protected:
int container = 0;
};
struct Derived:public Base
{
Derived(Base b):Base(b){}
using Base::container;
};
int main()
{
Base a;
cout<<Derived(a).container<<endl;
}
举个实际的例子
// Extracts a reference to the container from back_insert_iterator.
template <typename Container>
inline auto get_container(std::back_insert_iterator<Container> it)
-> Container& {
using base = std::back_insert_iterator<Container>;
struct accessor : base {
accessor(base b) : base(b) {}
using base::container;
};
return *accessor(it).container;
}
对泛化类模板进行特化以达到编译期约束
template <typename T> struct is_char : std::false_type {};
template <> struct is_char<char> : std::true_type {};
对泛化类模板进行继承以达到编译期约束
struct compile_string {};
template <typename S>
struct is_compile_string : std::is_base_of<compile_string, S> {};
还有一个例子:
template <typename T> struct is_integral : std::is_integral<T> {};
template <> struct is_integral<int128_opt> : std::true_type {};
template <> struct is_integral<uint128_t> : std::true_type {};
还有一个例子:
template <typename Char> struct formatter<short, Char> : formatter<int, Char> {}
对返回值进行SFINAE达到编译期约束
#include <iostream>
#include <type_traits>
template <typename T>
typename std::enable_if<std::is_integral<T>::value, void>::type
printValue(T value) {
std::cout << "Integral value: " << value << std::endl;
}
template <typename T>
typename std::enable_if<std::is_floating_point<T>::value, void>::type
printValue(T value) {
std::cout << "Floating point value: " << value << std::endl;
}
int main() {
printValue(42); // 调用第一个重载,输出:Integral value: 42
printValue(3.14); // 调用第二个重载,输出:Floating point value: 3.14
printValue("hello"); // 不匹配任何重载,编译时不会产生错误
return 0;
}
萃取数组长度
注意看这里的`size_t N`
// Converts a compile-time string to basic_string_view.
template <typename Char, size_t N>
constexpr auto compile_string_to_view(const Char (&s)[N])
-> basic_string_view<Char> {
// Remove trailing NUL character if needed. Won't be present if this is used
// with a raw character array (i.e. not defined as a string).
return {s, N - (std::char_traits<Char>::to_int_type(s[N - 1]) == 0 ? 1 : 0)};
}
template <typename Char>
constexpr auto compile_string_to_view(detail::std_string_view<Char> s)
-> basic_string_view<Char> {
return {s.data(), s.size()};
}
区分编译期与运行期
template <typename Char, typename InputIt, typename OutputIt>
constexpr auto copy_str(InputIt begin, InputIt end, OutputIt out)
-> OutputIt {
while (begin != end) *out++ = static_cast<Char>(*begin++);
return out;
}
template <typename Char, typename T, typename U,
std::enable_if_t<std::is_same<remove_const_t<T>, U>::value&& is_char<U>::value>>
constexpr auto copy_str(T* begin, T* end, U* out) -> U* {
if (is_constant_evaluated()) return copy_str<Char, T*, U*>(begin, end, out);
auto size = to_unsigned(end - begin);
if (size > 0) memcpy(out, begin, size * sizeof(U));
return out + size;
}
对类模板进行调用达到接口约束
template <typename Char, typename Handler>
FMT_CONSTEXPR auto parse_replacement_field(const Char* begin, const Char* end,
Handler&& handler) -> const Char* {
struct id_adapter {
Handler& handler;
int arg_id;
FMT_CONSTEXPR void on_auto() { arg_id = handler.on_arg_id(); }
FMT_CONSTEXPR void on_index(int id) { arg_id = handler.on_arg_id(id); }
FMT_CONSTEXPR void on_name(basic_string_view<Char> id) {
arg_id = handler.on_arg_id(id);
}
};
++begin;
if (begin == end) return handler.on_error("invalid format string"), end;
if (*begin == '}') {
handler.on_replacement_field(handler.on_arg_id(), begin);
} else if (*begin == '{') {
handler.on_text(begin, begin + 1);
} else {
auto adapter = id_adapter{handler, 0};
只是这一段,对于Handler的接口约束就有很多了,而且都是必须实现的。