递归可变模板不能推导参数 [英] recursive variadic template can't deduce argument

查看:240
本文介绍了递归可变模板不能推导参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个递归函数模板,其中类型'T'在内部使用,但可变参数模板参数仅用于生成递归模板。

 code> int qi(int t){
return 0;
}

template< typename T,typename ... U>
int qi(int t){
// do stuff ...
return qi< U ...>(t); //< --- error here
}



如果我尝试编译它,我得到错误无法推导'T'的模板参数。为什么不能将函数推导到qi的非模板变体( int qi(int t){} )?

解决方案

你遇到的问题是 qi<>(int) qi(int)不是相同的调用 - 前者仍然是一个模板,所以重载你试图写作为你的基本案例实际上不是。它实际上比最初明显的解决方案更糟:

 模板< 
int qi(int){...}

不是你的 qi 的一个明确的专门化(因为你的函数模板至少需要一个类型)。最简单的事情是使用实参来重载:

  template< typename ...> struct sequence {}; 

template< typename ... T>
int qi(int t){return qi_helper(t,sequence< T ...> {}); }

有:

  template< typename T,typename ... U> 
int qi_helper(int t,sequence< T,U ...>){
// do stuff
return qi_helper(t,sequence< U ...> {}) ;
}

int qi_helper(int t,sequence<>){
// base case
}
/ pre>

你可以使用struct QiHelper< T ...> 对于这两种情况(因为您可以部分专门化类模板)。



如果您不想返回任何内容,可以转到以下这样的帮助:

  template< typename T> void qi_helper(int t){
/ *单个类型的逻辑* /
}

template< typename ... T&
void qi(int t){
using swallow = int [];
(void)swallow {0,
(void(qi_helper (t)),0)...
};
}

根据您实际要返回的内容,可能。


I have a recursive function template where type 'T' is used internally but the variadic template argument is used only for generate the recursive template.

int qi(int t) {
    return 0;
}

template <typename T, typename... U>
int qi(int t) {
    //do stuff...
    return qi<U...>(t); // <--- error here
}

If I try to compile it, I get the error could not deduce template argument for 'T'. Why can't the function be deduced to the non template variant of qi (int qi(int t){}) ?

解决方案

The problem you're running into is that qi<>(int ) and qi(int ) are not the same call - the former is still a template, so the overload you attempted to write as your base case actually isn't. It's actually worse since the initially obvious solution:

template <>
int qi(int ) { ... }

since won't work since that isn't an explicit specialization of your qi (since your function template takes at least one type). The simplest thing would be to actually use arguments to overload with:

template <typename...> struct sequence { };

template <typename... T>
int qi(int t) { return qi_helper(t, sequence<T...>{} ); }

With:

template <typename T, typename... U>
int qi_helper(int t, sequence<T, U...> ) {
    // do stuff
    return qi_helper(t, sequence<U...>{}); 
}

int qi_helper(int t, sequence<> ) {
    // base case
}

You can accomplish a similar thing with a struct QiHelper<T...> that is specialized for the two cases (since you can partially specialize a class template).

If you didn't want to return anything, you could forward to a helper like this:

template <typename T> void qi_helper(int t) {
    /* logic for single type */
}

template <typename... T>
void qi(int t) {
    using swallow = int[];
    (void)swallow{0,
        (void(qi_helper<T>(t)), 0)...
    };
}

Depending on what you actually want to return, that may or may not still be possible.

这篇关于递归可变模板不能推导参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆