C++带有可变参数模板的无效参数

C++ void argument with variadic template

本文关键字:参数 无效 变参 C++      更新时间:2023-10-16

我的C++类中有以下模板:

template <typename ReturnType, typename... Args>
ReturnType run(void* context, const Args&... args) {
  /* Do the actual job. */
}

出于实际原因,我需要为 ReturnType void 指定它。我需要保留参数列表,因为它们仍然有用。

我尝试了以下方法,但都不起作用:

template <typename... Args>
void run(void* context, const Args&... args) {
  /* Do the actual job. */
}

template <typename ReturnType = void, typename... Args>
void run(void* context, const Args&... args) {
  /* Do the actual job. */
}

那么.. 在我的示例中使用 void 参数指定的正确方法是什么?

在 C++17 中,这很简单: 使用 if constexpr

template <typename ReturnType, typename... Args>
ReturnType run(void* context, const Args&... args) {
    if constexpr (std::is_void_v<ReturnType>) {
        /* void case */
    } else {
        /* non-void case */
    }
}

在 C++17 之前,最好的方法是使用标记调度。创建一个仅对类型进行编码的新类模板,以便可以将其作为参数传递:

template <typename T> struct tag { };
template <typename ReturnType, typename... Args>
ReturnType run_impl(tag<ReturnType>, void* context, const Args&... args) {
    /* non-void case */
}
template <typename... Args>
void run_impl(tag<void>, void* context, const Args&... args) {
    /* void case */
}
template <typename ReturnType, typename... Args>
ReturnType run(void* context, const Args&... args) {
    return run_impl(tag<ReturnType>{}, context, args...);
}