Home > Back-end >  C Template specialization with variable template parameter count
C Template specialization with variable template parameter count

Time:03-10

I have the problem, that i have a template<typename R, typename... ArgTs> class that should have a function R call(ArgTs... args). The Problem is, that i need a special case, where R is void. I already tried std::is_same<...> with constexpr but this is not possible as i use c 11.

Here i have broken down the problem to the two functions and how i think it sould look like:

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);
}

The compiler gives this error: error: non-type partial specialization 'call<void, ArgTs ...>' is not allowed

I understand why, as the two templates are basically the same, as they accept as many parameters as you want, but how can i solve this problem?

The function should also be inside of a class as method (template class ...), but with the two functions i wrote i could build only a wrapper inside the class to make the template thing simpler.

CodePudding user response:

Function templates can't be partial specified, you can overload them.

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) {
    ...
}
  • Related