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) >() );
}