每个可变参数模板参数生成一个类成员 [英] Generating one class member per variadic template argument

查看:155
本文介绍了每个可变参数模板参数生成一个类成员的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个模板类,其中每个模板参数代表内部计算可以处理的一种类型的值。需要模板(而不是函数重载),因为这些值作为boost :: any传递,并且它们的类型在运行时之前不明确。

I have a template class where each template argument stands for one type of value the internal computation can handle. Templates (instead of function overloading) are needed because the values are passed as boost::any and their types are not clear before runtime.

为了正确地转换为正确的类型,我想为每个可变参数类型提供一个成员列表,如下所示:

To properly cast to the correct types, I would like to have a member list for each variadic argument type, something like this:

template<typename ...AcceptedTypes> // e.g. MyClass<T1, T2>
class MyClass {
    std::vector<T1> m_argumentsOfType1;
    std::vector<T2> m_argumentsOfType2; // ...
};

或者,我想将模板参数类型存储在列表中,以执行一些操作RTTI魔术(?)。但是我还不清楚如何将它们保存在std :: initializer_list成员中。

Or alternatively, I'd like to store the template argument types in a list, as to do some RTTI magic with it (?). But how to save them in a std::initializer_list member is also unclear to me.

感谢您的帮助!

推荐答案

正如您已经暗示的,最好的方法是使用元组:

As you have already been hinted, the best way is to use a tuple:

template<typename ...AcceptedTypes> // e.g. MyClass<T1, T2>
class MyClass {
    std::tuple<std::vector<AcceptedTypes>...> vectors;
};

这是乘以字段的唯一方法,因为您无法神奇地使它拼写出字段名称。另一个重要的事情可能是获得对它们的一些命名访问。我想您要实现的是拥有多个具有 unique 类型的向量,因此您可以使用以下工具按其值类型搜索正确的向量:

This is the only way to multiply the "fields" because you cannot magically make it spell up the field names. Another important thing may be to get some named access to them. I guess that what you're trying to achieve is to have multiple vectors with unique types, so you can have the following facility to "search" for the correct vector by its value type:

template <class T1, class T2>
struct SameType
{
    static const bool value = false;
};

template<class T>
struct SameType<T, T>
{
    static const bool value = true;
};

template <typename... Types>
class MyClass
{
     public:
     typedef std::tuple<vector<Types>...> vtype;
     vtype vectors;

     template<int N, typename T>
     struct VectorOfType: SameType<T,
        typename std::tuple_element<N, vtype>::type::value_type>
     { };

     template <int N, class T, class Tuple,
              bool Match = false> // this =false is only for clarity
     struct MatchingField
     {
         static vector<T>& get(Tuple& tp)
         {
             // The "non-matching" version
             return MatchingField<N+1, T, Tuple,
                    VectorOfType<N+1, T>::value>::get(tp);
         }
     };

     template <int N, class T, class Tuple>
     struct MatchingField<N, T, Tuple, true>
     {
        static vector<T>& get(Tuple& tp)
        {
            return std::get<N>(tp);
        }
     };

     template <typename T>
     vector<T>& access()
     {
         return MatchingField<0, T, vtype,
                VectorOfType<0, T>::value>::get(vectors);
     }
};

这里是测试用例,因此您可以尝试一下:

Here is the testcase so you can try it out:

int main( int argc, char** argv )
{
    int twelf = 12.5;
    typedef reference_wrapper<int> rint;

    MyClass<float, rint> mc;
    vector<rint>& i = mc.access<rint>();

    i.push_back(twelf);

    mc.access<float>().push_back(10.5);

    cout << "Test:\n";
    cout << "floats: " << mc.access<float>()[0] << endl;
    cout << "ints: " << mc.access<rint>()[0] << endl;
    //mc.access<double>();

    return 0;
}

如果使用的类型不在传递给的类型列表中专门化MyClass(请参阅此注释掉的访问权限以获取双精度),您将得到一个编译错误,但不太可读,但是gcc至少指出了导致问题的正确位置,并且至少这样的错误消息表明了导致错误的正确原因。问题-例如,如果您尝试执行 mc.access< double>()

If you use any type that is not in the list of types you passed to specialize MyClass (see this commented-out access for double), you'll get a compile error, not too readable, but gcc at least points the correct place that has caused the problem and at least such an error message suggests the correct cause of the problem - here, for example, if you tried to do mc.access<double>():

 error: ‘value’ is not a member of ‘MyClass<float, int>::VectorOfType<2, double>’

这篇关于每个可变参数模板参数生成一个类成员的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆