Đây là cách để thực hiện điều đó. Với lớp học của bạn mẫu some_other_type
:
template<int I, int J>
struct some_other_type { };
Và đưa ra một số máy móc thiết bị ẩn trong detail
namespace:
namespace detail
{
template<int... Is>
struct pairs { };
template<int I, int J>
struct pairs<I, J>
{
using type = std::tuple<some_other_type<I, J>>;
};
template<int I, int J, int... Is>
struct pairs<I, J, Is...>
{
using type = decltype(std::tuple_cat(
std::tuple<some_other_type<I, J>>(),
typename pairs<J, Is...>::type()));
};
}
Bạn có thể cung cấp một chức năng đơn giản mà instantiates mẫu lớp helper:
template<int... Is>
typename detail::pairs<Is...>::type pairs()
{
return typename detail::pairs<Is...>::type();
}
Và đây là cách bạn sẽ sử dụng nó (và một trường hợp thử nghiệm):
#include <type_traits>
int main()
{
auto p = pairs<1, 2, 3, 4>();
// Won't fire!
static_assert(
std::is_same<
decltype(p),
std::tuple<
some_other_type<1,2>,
some_other_type<2,3>,
some_other_type<3,4>>
>::value,
"Error!");
}
Cuối cùng, đây là live example.
CẢI THIỆN: (tại sao viết <1, 2, 3, 4>
khi người ta có thể viết <1, 5>
)?
Cũng có thể mở rộng giải pháp trên để không cần phải viết thủ công mọi số giữa giá trị tối thiểu và tối đa làm đối số mẫu của pairs()
. Với máy móc thiết bị bổ sung bên dưới, một lần nữa ẩn trong một namespace detail
:
namespace detail
{
template <int... Is>
struct index_list { };
template <int MIN, int N, int... Is>
struct range_builder;
template <int MIN, int... Is>
struct range_builder<MIN, MIN, Is...>
{
typedef index_list<Is...> type;
};
template <int MIN, int N, int... Is>
struct range_builder : public range_builder<MIN, N - 1, N - 1, Is...>
{ };
// Meta-function that returns a [MIN, MAX) index range
template<int MIN, int MAX>
using index_range = typename range_builder<MIN, MAX>::type;
template<int... Is>
auto pairs_range(index_list<Is...>) -> decltype(::pairs<Is...>())
{
return ::pairs<Is...>();
}
}
Có thể định nghĩa một hàm helper pairs_range()
mà chấp nhận 2 đối số mẫu xác định phạm vi [begin, end)
- nơi end
không được bao gồm, trong phong cách của Thư viện Tiêu chuẩn:
template<int I, int J>
auto pairs_range() -> decltype(pairs_range(detail::index_range<I, J>()))
{
return pairs_range(detail::index_range<I, J>());
}
Và đây là cách người ta sẽ sử dụng nó (trong đó có một trường hợp thử nghiệm):
int main()
{
// Won't fire!
static_assert(
std::is_same<
decltype(pairs_range<1, 5>()),
decltype(pairs<1, 2, 3, 4>())
>::value,
"Error!");
}
Và một lần nữa, đây là live example.
+1 Đây có lẽ là có thể đạt được bằng cách sử dụng lớp ... –