将结构字段的类型展开为可变模板参数
Expand types of struct fields into variadic template arguments
假设我有一个这样的结构:
struct Foo {
int a;
float b;
bool c;
};
像这样的模板化函数:
template<typename ...Ts> void func();
如何编写一个使用Foo的字段类型调用func()
的函数,比如:expand<Foo>(); // will call func<int,float,bool>();
这个答案的灵感来自这里的片段。
一些技巧可以在C++17中使用结构化绑定来实现简单的静态反射。Boost::PFR(或上面提到的魔术(在检测到C++17时基本上使用相同的技术,但如果您不想导入该库,我将提供一个简化的实现:
#include <type_traits>
template <class T, class... TArgs>
decltype(void(T{std::declval<TArgs>()...}), std::true_type{}) test_is_braces_constructible(int);
template <class, class...>
std::false_type test_is_braces_constructible(...);
template <class T, class... TArgs>
using is_braces_constructible = decltype(test_is_braces_constructible<T, TArgs...>(0));
struct any_type {
template<class T>
constexpr operator T(); // non explicit
};
template<typename T, template <typename ...Unused> typename R>
constexpr auto extractTypes() noexcept {
using Type = std::decay_t<T>;
Type* tptr;
if constexpr(is_braces_constructible<Type, any_type, any_type>{}) {
auto& [ m0, m1 ] = *tptr;
return R< std::decay_t<decltype(m0)>, std::decay_t<decltype(m1)> > {};
} else if constexpr(is_braces_constructible<Type, any_type>{}) {
auto&& [m0] = *tptr;
return R< std::decay_t<decltype(m0)> > {};
} else {
return R<> {};
}
}
上述代码中的extractTypes()
接受聚合可初始化类型T
来反映,并接受可变模板R
来接收提取的类型。您可以将要对这些类型执行的操作放入结构R
:中
template <typename ...Types>
struct R {
static void doStuffs() {
(operation<Types>(), ...);
}
};
在上面的代码中,T
最多可以容纳2个成员,但您可以扩展实现以支持所需的成员数量。如果你觉得写那些样板文件很乏味,你可以试试我写的这个只有标题的实用程序。它使用宏生成支持任意数量成员的代码,但需要boost才能构建。
实现CCD_ 8思想,适用于c++17
或以上
如果您可以使用所需的类型为结构提供元组成员;
你可以像下面这样做;
struct Foo
{
std::tuple<int, float, bool> tpl_;
};
template <class...Ts>
void test( Ts... ) {}
int main()
{
Foo f;
std::apply( []( auto&&...args ) { test( args... ); }, f.tpl_ );
}
好点@user975989
相关文章:
- 将结构字段的类型展开为可变模板参数
- python.clang AST 解析:获取字段声明的 c++ 模板参数
- 将带有字段的表作为参数从C++传递给 Lua 函数?
- C++中的可变参数函子可以支持命名字段吗?
- 可以将模板字段参考模板参数作为第一个模板参数传递
- 委托构造函数在使用类字段进行参数时会出现分段错误
- 函数从模板参数中获取字段值,而不是直接访问以允许对相同信息使用不同的名称
- 如何初始化结构字段 std::map<std::string, std::string>称为参数
- 在构造函数中初始化const字段,但首先检查一个参数
- 函数作为具有 THAT 函数作为模板参数的类的字段的模板参数
- Qt在主窗口字段中从主窗口获取ui参数
- OpenCV错误:cvGetMat中有错误的标志(参数或结构字段)(无法识别或不支持的数组类型)
- g++将基构造函数错误为字段,并忽略它的参数
- 返回类型取决于静态参数包字段
- std::make_shared 在使用位字段中的参数进行构造时无法编译
- 具有不同模板参数的相同类无法访问彼此的私有字段
- ADO 创建参数在尝试从 C++ 写入 Oracle 的 RAW(16) 字段时失败并出现0x800A0D5D
- 如何将对象字段作为函数参数(特征向量)传递
- 对象数组参数 - 错误:字段“字母”的类型不完整
- 在C++中将默认参数设置为nullptr和非静态类字段