静态递归元组

时间:2015-01-25 20:54:22

标签: c++ templates c++11

我希望能够通过递归包装另一个带有一些额外类型信息的元组来静态地创建一个元组。

一个简单的例子是:

std::tuple<int, float> MyTuple;
std::tuple<Matrix<int, 2, 3>, Matrix<float, 4, 5>> WrappedMyTuple;

以下是我为实现此包装而实现的代码的完整示例(道歉,因为我提交的实现被代码库的详细信息混淆了,我将它从中抽出来。):

#include <iostream>
#include <tuple>
using namespace std;

template <typename PRECISION, int R, int C>
struct Matrix
{
    Matrix() {}
};

template <typename DERIVED>
struct VariableTraits
{
    //        static const int DIM;
};

template <typename DERIVED>
struct WrappedTraits
{
    //        static const int DIM;
    //        typedef std::tuple<VARIABLE0, VARIABLE1, ...> VARIABLES;
};

template <int N, typename WRAPPER>
struct WrappedType
{
    typedef WrappedTraits<WRAPPER> Traits;
    static const int DIM = Traits::DIM;
    typedef typename Traits::VARIABLES VARIABLES;
    typedef Matrix<float, Traits::DIM, VariableTraits<typename std::tuple_element<N, VARIABLES>::type>::DIM> type;
};

template<int N, typename WRAPPER>
struct MatrixTypeImpl
{
    typedef std::tuple<typename WrappedType<N, WRAPPER>::type, typename MatrixTypeImpl<N - 1, WRAPPER>::type> type;
};

template <typename WRAPPER>
struct MatrixTypeImpl<0, WRAPPER>
{     
    typedef typename WrappedType<0, WRAPPER>::type type;
};

template<typename WRAPPER>
struct MatrixType
{
    typedef WrappedTraits<WRAPPER> Traits;
    typedef MatrixTypeImpl<std::tuple_size<typename Traits::VARIABLES>::value - 1, WRAPPER> type;
};

struct FooVariable
{
};

struct BarVariable
{
};

template <>
struct VariableTraits<FooVariable>
{
    static const int DIM = 2;
};

template <>
struct VariableTraits<BarVariable>
{
    static const int DIM = 3;
};

struct Wrapper
{
};

template <>
struct WrappedTraits<Wrapper>
{
    static const int DIM = 2;
    typedef std::tuple<FooVariable, BarVariable> VARIABLES;
};

template <int N, typename WRAPPER>
void hello(const typename std::tuple_element<N, typename MatrixType<WRAPPER>::type>::type& mat)
{

}

int main()
{
    typedef WrappedTraits<Wrapper> Traits;
    typedef typename Traits::VARIABLES VARIABLES;
    typedef typename MatrixType<Wrapper>::type MatrixTuple;

    Matrix<float, 2, 2> FooMatrix;
    Matrix<float, 2, 3> BarMatrix;

    hello<0, Wrapper>(FooMatrix);   
    hello<1, Wrapper>(BarMatrix);   

    return 0;
}

ideone link

这将无法编译,因为它无法推断出模板参数:

prog.cpp: In function 'int main()':
prog.cpp:98:29: error: no matching function for call to 'hello(Matrix<float, 2, 2>&)'
  hello<1, Wrapper>(FooMatrix); 
                             ^
prog.cpp:98:29: note: candidate is:
prog.cpp:84:6: note: template<int N, class WRAPPER> void hello(const typename std::tuple_element<N, typename MatrixType<WRAPPER>::type>::type&)
 void hello(const typename std::tuple_element<N, typename MatrixType<WRAPPER>::type>::type& mat)
      ^
prog.cpp:84:6: note:   template argument deduction/substitution failed:
prog.cpp: In substitution of 'template<int N, class WRAPPER> void hello(const typename std::tuple_element<N, typename MatrixType<WRAPPER>::type>::type&) [with int N = 1; WRAPPER = Wrapper]':
prog.cpp:98:29:   required from here
prog.cpp:84:6: error: invalid use of incomplete type 'struct std::tuple_element<1u, MatrixTypeImpl<1, Wrapper> >'
In file included from /usr/include/c++/4.9/tuple:38:0,
                 from prog.cpp:2:
/usr/include/c++/4.9/utility:85:11: error: declaration of 'struct std::tuple_element<1u, MatrixTypeImpl<1, Wrapper> >'
     class tuple_element;
           ^

任何人都能更好地了解如何实现此包装或修复当前尝试的方法?

似乎不应该那么难。

0 个答案:

没有答案