Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

C++ Template specialization with variable template parameter count

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

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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.

>Solution :

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

Or if you still need the template parameter R for the 2nd function template, you can add the std::enable_if check for it too.

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) {
    ...
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading