У меня есть класс шаблона ProcessPromise<T> и его специализация ProcessPromise<void>, которая зависит от ProcessTask<T>:
template<typename T>
struct ProcessTask;
template<typename T>
class ProcessPromise
{
public:
ProcessTask<T> get_return_object();
};
template<>
class ProcessPromise<void>
{
public:
ProcessTask<void> get_return_object();
};
template<typename T>
struct ProcessTask
{
};
template<typename T>
ProcessTask<T> ProcessPromise<T>::get_return_object()
{
return { };
}
Не могу понять, как определить ProcessPromise<void>::get_return_object()?
Пробовал код ниже:
template<>
ProcessTask<void> ProcessPromise<void>::get_return_object()
{
return { };
}
но не компилируется, ошибка GCC:
prog.cc:30:23: error: template-id 'get_return_object<>' for 'ProcessTask<void> ProcessPromise<void>::get_return_object()' does not match any template declaration
30 | ProcessTask<void> ProcessPromise<void>::get_return_object()
| ^~~~~~~~~~~~~~~~~~~~
prog.cc:15:27: note: candidate is: 'ProcessTask<void> ProcessPromise<void>::get_return_object()'
15 | ProcessTask<void> get_return_object();
| ^~~~~~~~~~~~~~~~~
Ошибка MSVC:
error C2910: 'awl::ProcessPromise<void>::get_return_object': cannot be explicitly specialized





Просто удалите префикс template<>, как показано ниже:
//no prefix template<> needed here
inline ProcessTask<void> ProcessPromise<void>::get_return_object()
{
return { };
}
Обратите внимание, что добавлено ключевое слово inline, чтобы мы не получили множественную ошибку определения.
Причина, по которой нам не нужен префикс template<>, заключается в том, что мы предоставляем обычный внеклассное определение для функции-члена полной специализации шаблона класса. То есть мы на самом деле не специализируем функцию-член, а вместо этого предоставляем обычное (не шаблонное) определение вне класса для этой функции-члена.