Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
具有可变模板的C++空格参数 我在C++类中有以下模板: template <typename ReturnType, typename... Args> ReturnType run(void* context, const Args&... args) { /* Do the actual job. */ }_C++_Templates - Fatal编程技术网

具有可变模板的C++空格参数 我在C++类中有以下模板: template <typename ReturnType, typename... Args> ReturnType run(void* context, const Args&... args) { /* Do the actual job. */ }

具有可变模板的C++空格参数 我在C++类中有以下模板: template <typename ReturnType, typename... Args> ReturnType run(void* context, const Args&... args) { /* Do the actual job. */ },c++,templates,C++,Templates,出于实际原因,我需要为ReturnType void指定它。我需要保留arg列表,因为它们仍然有用 我尝试了以下方法,但均无效: template <typename... Args> void run(void* context, const Args&... args) { /* Do the actual job. */ } 及 所以。。在我的示例中,用void参数指定的正确方法是什么?在C++17中,这很简单:使用if constexpr: 在C++17之前,最

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

我尝试了以下方法,但均无效:

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


所以。。在我的示例中,用void参数指定的正确方法是什么?

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

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

在C++17中,这很简单:如果constexpr:

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

您试图做的是部分函数特化,这在C++中是不允许的。对于您试图解决的任何问题,您都需要找到不同的解决方案。@SamVarshavchik类似于包装器的东西?可能std::invoke可以帮助您是的,类似于包装器。您的函数成为一个包装器,std::将其参数转发给模板类的静态方法,该模板类使用与函数相同的模板参数。然后,您可以在专门化中使用适当的静态方法部分地专门化模板类的参数。这是一种相当常见的技术。你想做的是部分函数特化,这在C++中是不允许的。对于您试图解决的任何问题,您都需要找到不同的解决方案。@SamVarshavchik类似于包装器的东西?可能std::invoke可以帮助您是的,类似于包装器。您的函数成为一个包装器,std::将其参数转发给模板类的静态方法,该模板类使用与函数相同的模板参数。然后,您可以在专门化中使用适当的静态方法部分地专门化模板类的参数。这是一种相当普遍的技术。
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...);
}