可变参数模板的变量初始变量初始化

时间:2014-01-28 17:51:00

标签: c++ variadic-templates variadic-functions

我有一个模板化的A类,我想在其中调用另一个B类的模板化函数

标题如下:

template<typename... T> class A
{
public:
    A();
    void get(type_X params);
private:
    B b_;
};

和.hxx:

template<typename... T> void A<T...>::get(type_X params)
{
    /*here lies my problem*/
    T... variable; // just like we would do string s;
                   // and pass it to a function f(string& s) to assign it
    b_.get(params, variable...);
    /* do something with updated value of variable */
}

其中成员b_(B类)具有模板化函数get,它看起来像

template<typename... T> int B<T...>::get(type_X params, const T&... variable)
{
    /* change variable, just like we would assign a new value to a string& */
    return 0; 
}

而且我不知道如何初始化(如果可能的话)我的“T ...”对象作为模板化函数B :: get的参数给出。

感谢您的帮助

3 个答案:

答案 0 :(得分:3)

首先,索引机制在编译时创建一组整数索引:

template< std::size_t... Ns >
struct indices {
    typedef indices< Ns..., sizeof...( Ns ) > next;
};

template< std::size_t N >
struct make_indices {
    typedef typename make_indices< N - 1 >::type::next type;
};

template<>
struct make_indices< 0 > {
    typedef indices<> type;
};

现在,您可以创建一个对象数组:

T vars[] = { T()... };

接下来,您需要一个辅助函数来创建一个可以推导出整数包的上下文。像这样:

template<typename... T, T, size_t... I>
int helper(type_X params, T* arr, indices<I...>)
{
    return b_.get(params, arr[I]...);
}

对于arr参数,您将传递先前创建的数组vars,并传递最后一个make_indices<sizeof...(T)>::type()

希望有所帮助。

答案 1 :(得分:1)

首先,这是无效的语法:

T... variable;

要做这样的事情,你需要创建一个元组:

std::tuple<T...> variable;

然后使用其中一种技术以元组成员作为参数调用函数:

"unpacking" a tuple to call a matching function pointer Pass tuple's content as variadic function arguments How do I expand a tuple into variadic template function's arguments?

答案 2 :(得分:0)

以下内容可以帮助您:

#if 1 // Not in C++11
// Helper class to be able to use expansion of std::get<Index>(tuple)
template <int... Is> struct index_sequence {};

// Following create index_sequence<0, 1, 2, .., sizeof...(Is) - 1>
template <int Index, int... Is>
struct make_index_sequence { // recursively build a sequence of indices
    typedef typename make_index_sequence<Index - 1, Index -1, Is...>::type type;
};

template <int... Is>
struct make_index_sequence<0, Is...> { // stop the recursion when 0 is reached
    typedef index_sequence<Is...> type;
};
#endif

template<typename... Ts> class A
{
public:
    void get(type_X params)
    {
        std::tuple<Ts...> t;
        a.get(params, t, make_index_sequence<sizeof...(Ts)>());
    }
private:
    template<std::size_t ... Is>
    void get(type_X params, std::tuple<Ts...>& t, index_sequence<Is...>)
    {
        b_.get(params, std::get<Is>(t)...);
    }

private:
    B b_;
};