Mar*_*ayr 14 c++ templates variadic-templates c++11
我想要我的课
template <class T, unsigned int n>
class X;
Run Code Online (Sandbox Code Playgroud)
创建一个std::tuple包含n类型的时间T.这有什么特别巧妙的方法吗?对于任意可变参数模板类,还有一种很好的方法吗?
这是我先做的事情:
#include <tuple>
template <class, unsigned int, class>
struct simple_repeat_helper;
template <class T, unsigned int n, class... Args>
struct simple_repeat_helper<T, n, std::tuple<Args...>>
{
typedef typename simple_repeat_helper<T, n-1, std::tuple<Args..., T>>::type type;
};
template <class T, class... Args>
struct simple_repeat_helper<T, 0, std::tuple<Args...>>
{
typedef std::tuple<Args...> type;
};
template <class T, unsigned int n>
struct simple_repeat
{
using type = typename simple_repeat_helper<T, n, std::tuple<>>::type;
};
Run Code Online (Sandbox Code Playgroud)
但实际上,我不需要这个std::tuple,但对于另一个行为相似的类.所以我认为我会创建一个更通用的版本:
template <class, unsigned int, template <class...> class, class>
struct repeat_helper;
template <class T, template <class...> class M, class... Args>
struct repeat_helper<T, 0, M, M<Args...>>
{
typedef M<Args...> type;
};
template <class T, unsigned int n, template <class...> class M, class... Args>
struct repeat_helper<T, n, M, M<Args...>>
{
typedef typename repeat_helper<T, n-1, M, M<Args..., T>>::type type;
};
template <class T, unsigned int n, template <class...> class M = std::tuple>
struct repeat
{
using type = typename repeat_helper<T, n, M, M<>>::type;
};
Run Code Online (Sandbox Code Playgroud)
我以为我可以像这样使用它:
repeat<double, 5, std::tuple>::type x = std::make_tuple( 1., 2., 3., 4., 5. );
Run Code Online (Sandbox Code Playgroud)
但遗憾的是由于以下原因导致无法编译:
ambiguous class template instantiation for ‘struct repeat_helper<double, 0u, std::tuple, std::tuple<double, double, double, double, double> >’
Run Code Online (Sandbox Code Playgroud)
任何有关此错误的帮助将不胜感激!
我会这样做:
template<typename, typename>
struct append_to_type_seq { };
template<typename T, typename... Ts, template<typename...> class TT>
struct append_to_type_seq<T, TT<Ts...>>
{
using type = TT<Ts..., T>;
};
template<typename T, unsigned int N, template<typename...> class TT>
struct repeat
{
using type = typename
append_to_type_seq<
T,
typename repeat<T, N-1, TT>::type
>::type;
};
template<typename T, template<typename...> class TT>
struct repeat<T, 0, TT>
{
using type = TT<>;
};
Run Code Online (Sandbox Code Playgroud)
作为一个小测试:
#include <type_traits>
#include <tuple>
template<typename... Ts>
struct X { };
int main()
{
repeat<double, 5, std::tuple>::type t = std::make_tuple(1., 2., 3., 4., 5.);
static_assert(
std::is_same<
decltype(t),
std::tuple<double, double, double, double, double>
>::value, "!");
repeat<double, 3, X>::type y;
static_assert(
std::is_same<decltype(y), X<double, double, double>>::value, "!");
}
Run Code Online (Sandbox Code Playgroud)
最后,一个实例.
基于指数的解决方案:
template<typename Dependent, int Index>
using DependOn = Dependent;
// Assuming e.g. Indices<3> is indices<0, 1, 2>
template<typename T, int N, typename I = Indices<N>>
struct repeat;
template<typename T, int N, int... Indices>
struct repeat<T, N, indices<Indices...>> {
// Can be an actual type-list instead of (ab)using std::tuple
using type = std::tuple<DependOn<T, Indices>...>;
};
Run Code Online (Sandbox Code Playgroud)
template<typename Dependent, std::size_t Index>
using DependOn = Dependent;
template<typename T, std::size_t N, typename Indices = std::make_index_sequence<N>>
struct repeat;
template<typename T, std::size_t N, std::size_t... Indices>
struct repeat<T, N, std::index_sequence<Indices...>> {
using type = std::tuple<DependOn<T, Indices>...>;
};
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5496 次 |
| 最近记录: |