混合模板类型的模板参数包(std::使用可选参数重新创建函数)

Template parameter pack of mixed templated types (std::function recreation with optional arguments)

本文关键字:参数 新创建 创建 函数 类型 std 混合      更新时间:2023-10-16

我正在尝试制作一个支持具有默认值的可选参数的 std::function 替代方案。我尝试了几种不同的语法想法,但最现实的似乎是包含参数数据的专用模板的参数包。这是我想要的外部语法:

Function<
void /*Return type*/,
Arg<false, int> /*Required int parameter*/,
Arg<true, bool, true> /*Optional bool parameter that defaults to true*/
> func;

我本来想保持Function<ReturnType(args)>语法,但似乎您只能将类型名称放在括号中,而不能将类放在括号中。这是我当前的代码:

template<bool Optional, typename Type, Type Default>
class Arg;
template<typename Type, Type Default>
class Arg<false, Type, Default> {};
template<typename Type, Type Default>
class Arg<true, Type, Default> {};

问题 1:我找不到使"默认"参数对false专用化不是必需的方法。我已经尝试过使用默认构造函数的代理类,将第三个参数更改为指针并指定 nullptr(这在语法上并不理想)和对类型的常量引用(仍然需要用户端的三个参数),但似乎没有什么允许接受两个参数Function<false, Type>

问题 2:我找不到正确的语法来获取混合模板参数类型的参数包。我试过(显然语法无效)

template<typename RetType, Arg<bool, typename Type, Type>... args>
class Function{};

甚至是一个双重/嵌套模板,但我也无法完成这项工作。

所有这些间接关系确实源于这样一个事实,即您不能在类模板中有多个参数包,因此我必须找到创造性的方法来指定可选参数,但我会采取任何解决方案,我可以在编译时以某种方式制作此函数,而不必动态构造这些函数。

我正在使用C++20。

要在第一个参数false时使第三个模板参数可选,您可以使用带有std::enable_if的默认参数:

template <bool Optional, typename T,
T Default = std::enable_if_t<!Optional, T>{}>
class Arg;

这样,Arg<false, int>等价于Arg<false, int, 0>,而Arg<true, int>是格式错误的。


您可以使用泛型参数:

template <typename R, typename... Args>
class Function {
static_assert(std::conjunction_v<is_arg_v<Args>...>);
};

is_arg可以像这样简单的事情

template <typename T>
struct is_arg :std::false_type {};
template <bool Optional, typename T, T Default>
struct is_arg<Arg<Optional, T, Default>> :std::true_type {};
template <typename T>
inline constexpr bool is_arg_v = is_arg<T>::value;