不知何故 'using' 类型列表(在 C++17 及更高版本中)
Somehow 'using' a list of types (in C++17 and up)
如何才能使以下简单的想法发挥作用?
template <typename ...Types>
void Function()
{ /* do something that depends on the Types */ }
void Test()
{
using my_types = { int, float }; // not possible
using my_types = int, float; // alternative disallowed syntax
Function<my_types>();
Function<int,float>(); // OK, but I can't specify manually
}
为什么没有直接支持这种类型的列表?什么是简单的解决方法?
备注
- 这是在通用上下文中,我无法手动指定我想要的类型。
- 我不想将这些类型的对象传递给函数。它们可能很昂贵,或者只是不可复制。
澄清用例:用户定义了一个类似特征的class,其中他以某种方式指定了一个类型列表。稍后,我需要处理该列表。他如何指定它仍然是开放的。所以寻找一种简单的方法来做到这一点。不需要过于复杂的 'concat a type-list at compile-time' 模式,可以在此处的某处找到。
有可能的解决方法,主要使用 std::tuple
:
template <typename... Types>
void Function()
{ /* do something that depends on the Types */ }
template <typename... Types>
struct FunctionHelper<std::tuple<Types...>>
{ void operator ()() const { Function<Types...>(); } };
void Test()
{
using my_types = std::tuple<int, float>;
FunctionHelper<my_types>{}();
}
I don't want to pass objects of these types to the function
可能的解决方法是为此使用结构,如 std::type_identity(C++20 但很容易重写)
然后
void Test()
{
constexpr auto types = std::tuple{std::type_identity<int>{}, std::type_identity<float>{}};
std::apply([](auto... args){ Function<typename decltype(args)::type...>(); }, types);
}
一种可能的替代方法是定义一种类型包装器(如 std::tuple
但绝对不对模板参数做任何事情)
template <typename...>
struct type_wrapper
{ };
并声明Function()
接收该类型的对象
template <typename ...Types>
void Function (type_wrapper<Types...> const &)
{ /* do something that depends on the Types */ }
因此您可以将所需包装器的对象传递给 Function()
并让模板推导起作用
using my_wrapped_types = type_wrapper<int, float>;
Function(my_wrapped_types{});
Why is there no direct support for this kind type lists? What's a simple workaround?
因为 std::tuple
涵盖了大多数用例,而且如您所见,当您想要更轻便的东西时编写包装器是微不足道的。
I don't want to pass objects of these types to the function.
这样,您传递了一个 type_wrapper
类型的对象,但没有实例化任何引用类型。
如何才能使以下简单的想法发挥作用?
template <typename ...Types>
void Function()
{ /* do something that depends on the Types */ }
void Test()
{
using my_types = { int, float }; // not possible
using my_types = int, float; // alternative disallowed syntax
Function<my_types>();
Function<int,float>(); // OK, but I can't specify manually
}
为什么没有直接支持这种类型的列表?什么是简单的解决方法?
备注
- 这是在通用上下文中,我无法手动指定我想要的类型。
- 我不想将这些类型的对象传递给函数。它们可能很昂贵,或者只是不可复制。
澄清用例:用户定义了一个类似特征的class,其中他以某种方式指定了一个类型列表。稍后,我需要处理该列表。他如何指定它仍然是开放的。所以寻找一种简单的方法来做到这一点。不需要过于复杂的 'concat a type-list at compile-time' 模式,可以在此处的某处找到。
有可能的解决方法,主要使用 std::tuple
:
template <typename... Types>
void Function()
{ /* do something that depends on the Types */ }
template <typename... Types>
struct FunctionHelper<std::tuple<Types...>>
{ void operator ()() const { Function<Types...>(); } };
void Test()
{
using my_types = std::tuple<int, float>;
FunctionHelper<my_types>{}();
}
I don't want to pass objects of these types to the function
可能的解决方法是为此使用结构,如 std::type_identity(C++20 但很容易重写)
然后
void Test()
{
constexpr auto types = std::tuple{std::type_identity<int>{}, std::type_identity<float>{}};
std::apply([](auto... args){ Function<typename decltype(args)::type...>(); }, types);
}
一种可能的替代方法是定义一种类型包装器(如 std::tuple
但绝对不对模板参数做任何事情)
template <typename...>
struct type_wrapper
{ };
并声明Function()
接收该类型的对象
template <typename ...Types>
void Function (type_wrapper<Types...> const &)
{ /* do something that depends on the Types */ }
因此您可以将所需包装器的对象传递给 Function()
并让模板推导起作用
using my_wrapped_types = type_wrapper<int, float>;
Function(my_wrapped_types{});
Why is there no direct support for this kind type lists? What's a simple workaround?
因为 std::tuple
涵盖了大多数用例,而且如您所见,当您想要更轻便的东西时编写包装器是微不足道的。
I don't want to pass objects of these types to the function.
这样,您传递了一个 type_wrapper
类型的对象,但没有实例化任何引用类型。