C++中几个模板技巧(有点诡异的那种)

公开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的接口约束就有很多了,而且都是必须实现的。

  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值