模板元编程技巧练习

使用conditional控制分支

使用conditionalconditional_t来控制

1
2
std::conditional<true, int, float>::type x=3;
std::conditional<false, int, float>::type y=1.0f;

自己实现一个conditional的实现:

1
2
3
4
5
6
7
8
9
10
11
template <bool B, typename T, typename F>
struct conditional{
using type = T;
};
template <typename T, typename F>
struct conditional<false, T, F>{
using type = F;
};

template <bool B, typename T, typename F>
using conditiona_t = typename conditional<B,F,T>::type;

使用模板偏特化来控制分支

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
struct A;
struct B;

template <typename T>
struct Fun_ {
constexpr static size_t value = 0;
};

template <>
struct Fun_<A> {
constexpr static size_t value = 1;
}

template <>
struct Fun_<B>{
constexpr static size_t value = 2;
}

constexpr size_t h = Fun_<B>::value;

使用C++14, 可以有另一种方式写作:

1
2
3
4
5
6
7
8
9
// 第二种实现:
template <typename T>
constexpr size_t Fun = 0;

template <>
constexpr size_t Fun<A> = 1;

template <>
constexpr size_t Fun<B> = 2;

求所有参数的和:

第一种写法:

1
2
3
4
5
template <size_t... inputs>
constexpr size_t sum1 = 0;

template <size_t cur_input, size_t... inputs>
constexpr size_t sum1<cur_input, inputs...> = cur_input + sum1<inputs...>;

第二种写法(C++17支持):

1
2
3
4
5
template <size_t... inputs>
constexpr size_t sum2()
{
return (0 + ... + inputs);
}

测试代码:

1
2
3
4
5
auto v1 = sum1<10,3,2,1>;
std::cout << "sum1<10,3,2,1> = " << v1 << std::endl;

auto v2 = sum2<10, 3, 2, 1>();
std::cout << "sum2<10,3,2,1> = " << v2 << std::endl;

计算Sigma(a,b) = 1 + 2 + … + (a+b)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 计算累加求和 sigma(a,b) = 1 + 2 + ... + (a+b)
template <size_t ID>
struct sigma_impl {
constexpr static size_t value = ID + sigma_impl<ID - 1>::value;
};

template <>
struct sigma_impl<0> {
constexpr static size_t value = 0;
};

template <size_t A>
struct Sigma_ {
template <size_t ID>
constexpr static size_t value = sigma_impl<ID + A>::value;
};

// 测试代码:
auto v1 = Sigma_<2>::value<3>;
std::cout << "Sigma = " << v1 << std::endl; // 结果为15