C++ 不同变量模板展开

C++ 不同变量模板展开,c++,c++11,variadic-templates,c++14,C++,C++11,Variadic Templates,C++14,我想使用可变模板从结构中准备值对列表 #include <vector> struct foo { foo(int a, int b) : a(a), b(b) {} int a; int b; }; struct Msg { std::vector<int> valueArray; }; template<typename... Args> Msg func(Args... args) {

我想使用可变模板从结构中准备值对列表

#include <vector>

struct foo
{
    foo(int a, int b)
        : a(a), b(b) {}
    int a;
    int b;
};

struct Msg
{
    std::vector<int> valueArray;    
};

template<typename... Args>
Msg func(Args... args)
{
    Msg msg;
    msg.valueArray = { sizeof...(args), (args.a)..., (args.b)... };
    return msg;
}

int main() {
    Msg msg = func(foo{1,2}, foo{3,4}, foo{5,6});
}
#包括
结构foo
{
foo(内部a、内部b)
:a(a),b(b){}
INTA;
int b;
};
结构味精
{
向量值数组;
};
模板
Msg func(Args…Args)
{
味精;
msg.valueArray={sizeof…(args),(args.a)…,(args.b)…};
返回味精;
}
int main(){
Msg Msg=func(foo{1,2},foo{3,4},foo{5,6});
}
func将返回的消息将具有
valueArray=[3,1,3,5,2,4,6]


如果valueArray看起来像[3,1,2,3,4,5,6]?

使用C++14功能,可以得到一个通用的解决方案:

struct Msg {
    std::vector<int> values;
};

template <std::size_t... indices, typename Tuple, typename OutputIt>
void copy(std::index_sequence<indices...>, Tuple&& t, OutputIt out) {
    (void)std::initializer_list<int> {
        (*out++ = std::get<indices>(std::forward<Tuple>(t)), 0)...
    };
}

template <typename Tuple, typename OutputIt>
void copy(Tuple&& t, OutputIt out) {
    copy(std::make_index_sequence<std::tuple_size<std::decay_t<Tuple>>{}>{},
         std::forward<Tuple>(t), out);
}

template <typename... Args>
Msg func(Args... args) {
    auto cat = std::tuple_cat(args...);
    Msg m{{sizeof...(args)}};
    copy(cat, std::back_inserter(m.values));
    return m;
}

// For demonstration:
template <typename... T>
auto foo(T&&... t) {return std::make_tuple(std::forward<T>(t)...);}


您也可以将
foo
定义为(固定大小)元组,例如使用foo=std::tuple的
,则上面的示例编译时不使用辅助函数(当然,在调整大括号后)。

以下内容并不像我想的那样通用,但可能对您来说已经足够了:

template<typename Arr, std::size_t... Is>
Msg func2( const Arr& arr, std::index_sequence<Is...> )
{
    Msg msg;
    msg.valueArray = {
        sizeof...(Is) / 2,
        ( ( Is % 2 == 0 ) ? std::get< Is / 2 >( arr ).a
                          : std::get< Is / 2 >( arr ).b )... };
    return msg;
}

template<typename... Args>
Msg func(Args... args)
{
    return func2( std::forward_as_tuple( args... ),
                  std::make_index_sequence< 2*sizeof...(Args) >() );
}
模板
Msg func2(常量Arr&Arr,标准::索引_序列)
{
味精;
msg.valueArray={
(Is)/2的规模,
((Is%2==0)?std::get(arr).a
:std::get(arr.b);
返回味精;
}
模板
Msg func(Args…Args)
{
返回func2(std::forward_as_tuple(args…),
std::make_index_sequence<2*sizeof…(Args)>();
}

您无法分配到数组。我已更改为vector,但这与此问题无关;)考虑到您的问题不使用编译时值,在分配置乱值后调用
std::sort
是否不可行?@chris我使用1,2,3,4,5,6值来轻松指出我希望接收的数组顺序。在我的应用程序中,foo值没有任何顺序,它们是编译时已知的。哦,我明白了。对不起,我有点担心运行时开销是什么原因,但OPs问题不容易以一种无开销且优雅的方式解决——我的答案并不是更好,只是不同而已+1要使用空包编译的邮件。为什么不使用
forward\u as\u tuple
而不是指针数组?
template<typename Arr, std::size_t... Is>
Msg func2( const Arr& arr, std::index_sequence<Is...> )
{
    Msg msg;
    msg.valueArray = {
        sizeof...(Is) / 2,
        ( ( Is % 2 == 0 ) ? std::get< Is / 2 >( arr ).a
                          : std::get< Is / 2 >( arr ).b )... };
    return msg;
}

template<typename... Args>
Msg func(Args... args)
{
    return func2( std::forward_as_tuple( args... ),
                  std::make_index_sequence< 2*sizeof...(Args) >() );
}