具有可变模板参数计数的 C++ 模板专业化

C++ Template specialization with variable template parameter count

我有一个问题,我有一个 template<typename R, typename... ArgTs> class 应该有一个函数 R call(ArgTs... args)。问题是,我需要一个特殊情况,其中 R 是无效的。我已经尝试过 std::is_same<...>constexpr 但这是不可能的,因为我使用 c++11.

在这里,我将问题分解为两个函数以及我认为它应该是什么样子:

template <typename R, typename... ArgTs>
R call(Callable<R, ArgTs...> *_callback, SemaphoreHandle_t _mutex, ArgTs... args) {
    xSemaphoreTakeRecursive(_mutex, portMAX_DELAY);

    if (_callback != nullptr) {
        if (_callback->isAlive()) {
            R returnVal = _callback->call(args...);
            xSemaphoreGiveRecursive(_mutex);
            return returnVal;
        }
    }

    xSemaphoreGiveRecursive(_mutex);
    return (R)0;
}

template <typename... ArgTs>
void call<void, ArgTs...>(Callable<void, ArgTs...> *_callback, SemaphoreHandle_t _mutex,
                        ArgTs... args) {
    xSemaphoreTakeRecursive(_mutex, portMAX_DELAY);

    if (_callback != nullptr) {
        if (_callback->isAlive()) {
            _callback->call(args...);
        }
    }

    xSemaphoreGiveRecursive(_mutex);
}

编译器报错:error: non-type partial specialization 'call<void, ArgTs ...>' is not allowed

我明白为什么,因为这两个模板基本相同,你想要多少参数都可以接受,但是我该如何解决这个问题?

该函数也应该在 class 作为方法 (template class ...) 的内部,但是使用我编写的两个函数,我只能在 class 内部构建一个包装器来制作模板的事情更简单。

不能部分指定函数模板,您可以重载它们。

template <typename R, typename... ArgTs>
typename std::enable_if<!std::is_same<R, void>::value, R>::type 
call(Callable<R, ArgTs...> *_callback, SemaphoreHandle_t _mutex, ArgTs... args) {
    ...
}

template <typename... ArgTs>
void
call(Callable<void, ArgTs...> *_callback, SemaphoreHandle_t _mutex, ArgTs... args) {
    ...
}

或者如果您仍然需要第二个函数模板的模板参数 R,您也可以添加 std::enable_if 检查它。

template <typename R, typename... ArgTs>
typename std::enable_if<std::is_same<R, void>::value, R>::type 
call(Callable<R, ArgTs...> *_callback, SemaphoreHandle_t _mutex, ArgTs... args) {
    ...
}