可变参数模板与默认模板参数结合使用

And*_*joe 6 c++ template-meta-programming c++11

假设我有一堂课

enum CallbackType
{
    SYNC,
    ASYNC
}


template<CallbackType CB = SYNC, typename... Args>
class Callback
{
}
Run Code Online (Sandbox Code Playgroud)

我希望能够选择特定的回调类型,同时仍然能够拥有可变参数模板参数.现在我明白编译器不能区分它们,但也许有一些方法可以处理第一个模板参数是CallbackType的特定情况?

Callback<int int> //Should be Callback<SYNC, int, int>
Callback<ASYNC, int, int> //Should be Callback<ASYNC, int, int>
Run Code Online (Sandbox Code Playgroud)

Sam*_*hik 8

当涉及可变参数模板时,C++有两个方面,在您的情况下彼此冲突:

  1. 默认模板参数不应位于非默认模板参数之前.

  2. 变量模板参数不应位于非可变参数模板参数之前.

在许多情况下,当然可以正确声明和使用参数不遵循这些规则的模板,但这些情况对于此问题的目的并不重要.在您的情况下,它归结为两个模板参数都希望成为其模板中的最后一个参数,这是出于各自的原因.简而言之,这就是问题所在.

解决此冲突的最简单方法是使用内部模板:

template<CallbackType CB = ASYNC>
class CallbackClass {

public:

    template<typename... Args> class Callback
    {
    }
};
Run Code Online (Sandbox Code Playgroud)

然后,你的两个例子变成:

CallbackClass<>::Callback<int, int>
Run Code Online (Sandbox Code Playgroud)

CallbackClass<ASYNC>::Callback<int, int>
Run Code Online (Sandbox Code Playgroud)

当然,你最终会有更长的课程名称.但是,这是什么typedefusing是.例如:

template<typename ...Args>
using DefaultCallback=CallbackClass<>::Callback<Args...>;
Run Code Online (Sandbox Code Playgroud)

然后用

DefaultCallback<int, int>
Run Code Online (Sandbox Code Playgroud)