template <int...> struct Z; template <int...> struct Q;
template <std::size_t...> struct I;
假設我們要
accumulated_sums<Z<1,2,3,4,5>, Q>::type
是
Q<1,3,6,10,15>
和
accumulated<I<1,2,3,4,5>, std::integer_sequence>::type
是
std::index_sequence<1,3,6,10,15>
有沒有辦法從accumulated_sums
類的一些繼承方案定義accumulated
類?它們的操作方式完全相同,唯一不同的是模板類型template <T...> class
對於accumulated_sums
而對於accumulated
稍有不同template <typename U, U...> class
。否則,即使它們的定義基本相同,我也必須分別定義這兩個類。應該有一些方法來爲兩個類定義一次。這裏是我爲這兩個類完全編譯的代碼,並且您可以看到它們在代碼中基本相同。
#include <iostream>
#include <type_traits>
#include <utility>
namespace detail {
template <typename Pack> struct sequence_traits;
template <typename T, template <T...> class Z, T... Is>
struct sequence_traits<Z<Is...>> {
using type = T;
template <T... Js>
using templ_type = Z<Js...>;
};
}
// accumulated_sums
template <typename T, typename Output, template <T...> class, T...> struct accumulated_sums_h;
template <typename T, template <T...> class Z, template <T...> class Q, T Sum, T... Is>
struct accumulated_sums_h<T, Z<Sum, Is...>, Q> {
using type = Q<Is..., Sum>;
};
template <typename T, template <T...> class Z, T Sum, T... Is, template <T...> class Q, T Next, T... Rest>
struct accumulated_sums_h<T, Z<Sum, Is...>, Q, Next, Rest...> :
accumulated_sums_h<T, Z<Sum + Next, Is..., Sum>, Q, Rest...> {};
template <typename Sequence,
template <typename detail::sequence_traits<Sequence>::type...> class = detail::sequence_traits<Sequence>::template templ_type>
struct accumulated_sums;
template <typename T, template <T...> class Z, T First, T... Rest, template <T...> class Q>
struct accumulated_sums<Z<First, Rest...>, Q> :
accumulated_sums_h<T, Z<First>, Q, Rest...> {};
// accumulated
template <typename T, typename Output, template <typename U, U...> class, T...> struct accumulated_h;
template <typename T, template <T...> class Z, template <typename U, U...> class Q, T Sum, T... Is>
struct accumulated_h<T, Z<Sum, Is...>, Q> {
using type = Q<T, Is..., Sum>;
};
template <typename T, template <T...> class Z, T Sum, T... Is, template <typename U, U...> class Q, T Next, T... Rest>
struct accumulated_h<T, Z<Sum, Is...>, Q, Next, Rest...> :
accumulated_h<T, Z<Sum + Next, Is..., Sum>, Q, Rest...> {};
template <typename Sequence, template <typename U, U...> class Q> struct accumulated;
template <typename T, template <T...> class Z, T First, T... Rest, template <typename U, U...> class Q>
struct accumulated<Z<First, Rest...>, Q> :
accumulated_h<T, Z<First>, Q, Rest...> {};
// Testing
template <int...> struct Z;
template <int...> struct Q;
template <std::size_t...> struct I;
int main() {
std::cout << std::boolalpha << std::is_same<
accumulated_sums<Z<1,2,3,4,5>, Q>::type,
Q<1,3,6,10,15>
>::value << '\n'; // true
std::cout << std::is_same<
accumulated_sums<Z<1,2,3,4,5>>::type,
Z<1,3,6,10,15>
>::value << '\n'; // true
std::cout << std::is_same<
accumulated<Z<1,2,3,4,5>, std::integer_sequence>::type,
std::integer_sequence<int, 1,3,6,10,15>
>::value << '\n'; // true
std::cout << std::is_same<
accumulated<I<1,2,3,4,5>, std::integer_sequence>::type,
std::index_sequence<1,3,6,10,15>
>::value << '\n'; // true
}
@ max66 [在C++ 17中編譯得很好](https://godbolt.org/g/5tKv7Z) – Justin
@Justin - thanks; right:C++ 17 – max66