2
struct VectorOfMaps {
  std::tuple<std::map<std::string,double>,
              std::map<std::string,int>,
              std::map<std::string,short>
            > tuple;
};

我想把它概括为一个模板,所以上面的类将由类似的东西产生

VectorOfMaps<3, std::string,double,
                std::string,int,
                std::string,short>

可以做到这一点或类似的事情吗?

我知道我可以将地图类型直接放入模板中,但这样的“ std::map”重复不会被认为有点难看吗?你怎么看?

(我考虑过是否可以std::pair在模板中指定类型,但不确定是否可以直接用于创建std::map类型)..

4

4 回答 4

3

由于您提到将对的专业化传递给类模板:

template<typename... Pairs>
struct VectorOfMaps {
    std::tuple<std::map<
        typename Pairs::first_type
        , typename Pairs::second_type
    >...> tuple;
};

这有效地std::pair用作类型列表——您也可以使用类似template<typename T, typename U> struct pair { using first_type = T; using second_type = U; };的东西。

也可以在没有 a 对的情况下传递类型,但这需要一些元计算。一个可能的解决方案:

// First argument is accumulator, supposed to be an empty tuple
template<typename Acc, typename... T> struct compute_tuple
{
    // Only triggered when the primary template is instantiated, which should
    // only happen if sizeof...(T) is odd -- it's possible to assert on that
    // instead, too.
    static_assert( !sizeof(Acc), "An even number of arguments is required" );
};

// Recursive case
template<typename... Acc, typename First, typename Second, typename... Rest>
struct compute_tuple<std::tuple<Acc...>, First, Second, Rest...>
: compute_tuple<std::tuple<Acc..., std::map<First, Second>>, Rest...> {};

// Terminal case
template<typename Acc>
struct compute_tuple<Acc> { using type = Acc; };

template<typename... T>
struct VectorOfMaps {
    /* 
     * You can assert that sizeof...(T) is even here; it might be more
     * helpful than an error deeper inside compute_tuple.
     */
    using tuple_type = typename compute_tuple<std::tuple<>, T...>::type;
    tuple_type tuple;
};
于 2013-05-04T23:57:40.810 回答
2

first_of_pair 元函数是不必要的,因为 pair 有 first_type 和 second_type 成员。这是带有可变参数模板参数的解决方案:

template<class... pairtypes>
struct VectorOfMaps
{
    std::tuple<
        std::map<
            typename pairtypes::first_type,
            typename pairtypes::second_type
        >...
    > tuple;
};

int main()
{
    VectorOfMaps<
        std::pair<int,char>,
        std::pair<char,long>
    > v;
    std::get<0>(v.tuple)[4]='a';
    std::get<1>(v.tuple)['z']=5l;
    return 0;
}
于 2013-05-04T23:56:51.317 回答
0

如果您可以接受要存储的地图数量的上限,则可以使用针对不同 n 值的模板特化来做到这一点:

template<int n, class key0, class value0, class key1 = void, class value1 = void>
struct VectorOfMaps;

template<class key0, class value0>
struct VectorOfMaps<1,key0,value0>
{
// ...
};

template<class key0, class value0, class key1, class value1>
struct VectorOfMaps<2,key0,value0,key1,value1>
{
// ...
};

更好的方法是使用可变参数模板参数。

从对参数中,您可以使用辅助元函数提取类型:

template<class T>
struct first_of_pair;

template<class First, class Second>
struct first_of_pair<std::pair<First,Second>>
{
   typedef First type;
};

// usage in a template where T is an std::pair: typename first_of_pair<T>::type
于 2013-05-04T23:35:22.500 回答
0

我认为使用 std::tuple 提供了一种更简单、更清洁的方式(但它可能会更慢......)。

template<int pos,typename... Args> struct TypeTransformer_ {
     using ValueType =  typename std::tuple_element<1,std::tuple<Args...>>::type;
     using KeyType =  typename std::tuple_element<0,std::tuple<Args...>>::type ;
     using Type =  decltype(std::tuple_cat(std::tuple<std::map<KeyType,ValueType>>(),
                    typename TypeTransformer_<pos - 2,Args...>::Type()));
};

//Base case with two elements...
template<typename... Args>
struct TypeTransformer_<2,Args...> {
   using ValueType  = typename std::tuple_element<1,std::tuple<Args...>>::type ;
   using KeyType =  typename std::tuple_element<0,std::tuple<Args...>>::type ;
   using Type =  std::tuple<std::map<KeyType,ValueType>> ;
};

//Handling the case of an odd number of parms
template<typename... Args> struct TypeTransformer_<1,Args...> ;

//Nicer interface so we don't have to specify the number of variadic param
template <typename... Args> struct SomeStruct{
using  TupleType = typename TypeTransformer_<sizeof...(Args),Args...>::Type;
TupleType tp ;
};
于 2013-05-05T02:15:16.433 回答