具有可变模板参数计数的 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) {
...
}
我有一个问题,我有一个 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) {
...
}