混合模板类型的模板参数包(带有可选参数的std :: function重新创建)

时间:2019-06-08 08:25:48

标签: c++

我试图做一个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专业化不需要“ Default”参数。我尝试了使用默认构造函数的代理类,将第三个参数更改为指针,并指定了nullptr(在语法上并不理想),以及对类型的const引用(从用户端仍然需要三个参数)但似乎没有什么允许Function<false, Type>接受两个参数。

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

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

甚至是双重/嵌套模板,但我也无法做到这一点。

所有这些间接性实际上源于您不能在类模板中包含多个参数包这一事实,因此我必须找到创造性的方法来指定可选参数,但是我将采取任何解决方案以某种方式使之成为现实。函数在编译时执行,而不必动态地构建这些函数。

我正在使用C ++ 20。

1 个答案:

答案 0 :(得分:1)

要在第一个参数为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;