问题很简单,我怎么能产生:
std::tuple<float, int, double>
如果我知道类型:
struct Foo { float a; int b; double c; };
我怎样才能在转换中检索数据?
答案 0 :(得分:9)
您无法在C ++中执行此操作,因为它需要一种称为 reflection 的语言功能。
相反,&#34;手动&#34;建立元组或者首先从元组开始。
或者,您可以使用Python(或类似)构建脚本来预处理代码并自动生成结果转换。
答案 1 :(得分:3)
正如其他答案所说,在C ++ 14中无法以通用方式执行此操作。
但是,C ++ 17中有一个使用结构化绑定的技巧:
template<typename T>
auto as_tuple_ref( T & t )
{
auto &[a,b,c] = t;
return std::tie(a,b,c);
}
struct Foo { float a; int b; double c; };
Foo bar;
int & b_ref = std::get<1>( as_tuple_ref(bar) );
此版本仅适用于具有3个成员的结构,但我相信只需花费一些时间和精力(以及一些SFINAE),就可以编写完全通用的解决方案(并且可能涉及大量复制粘贴)。
答案 2 :(得分:2)
您可以编写转换运算符。
struct Test {
int a;
float b;
double c;
explicit operator std::tuple<int, float, double>() const {
return {a, b, c};
}
};
然后,使用它:
int main() {
Test t{12, 3.2f, 4.5};
std::tuple tt = t;
}
答案 3 :(得分:1)
您可以手动执行此操作。例如:
#include <iostream>
#include <tuple>
using std::tuple;
using std::cout;
using std::endl;
using std::get;
struct Foo { float a; int b; double c; };
int main()
{
auto tuple_foo = tuple<decltype(Foo::a), decltype(Foo::b), decltype(Foo::c)>{1.1f, 10, 100.001};
cout << "<0>: " << get<0>(tuple_foo) << endl;
cout << "<1>: " << get<1>(tuple_foo) << endl;
cout << "<2>: " << get<2>(tuple_foo) << endl;
}
答案 4 :(得分:0)
基于这些成员名称,即:第一个成员称为a
,第二个成员称为b
,第三个成员称为c
。您可以定义以下结构模板member_type<>
,以获取每个成员的类型:
template<typename T>
struct member_type : T {
using a_t = decltype(T::a);
using b_t = decltype(T::b);
using c_t = decltype(T::c);
};
使用此别名模板tuple_splitter<>
,您可以使用此类成员(名为struct
,a
和b
)从c
定义元组:
template<typename T>
using tuple_splitter = std::tuple
<
typename member_type<T>::a_t,
typename member_type<T>::b_t,
typename member_type<T>::c_t
>;
然后,为您的Foo
:
tuple_splitter<Foo> foo_tuple;
foo_tuple
的类型为std::tuple<float, int, double>
。
如果您现在定义新的struct
,Bar
,则为:
struct Bar { int a; char b; float c; };
然后:
tuple_splitter<Bar> bar_tuple;
bar_tuple
的类型为std::tuple<int, char, float>
。
答案 5 :(得分:0)
使用std :: tie甚至可以更轻松:
struct foo
{
int value1;
int value2;
string str;
};
void main()
{
std::tuple<int, int, string> a{ 1, 1, "Hello " };
foo b;
std::tie(b.value1, b.value2, b.str) = a;
}