首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Args是怎么回事.,Args&.,Args&&

Args是怎么回事.,Args&.,Args&&
EN

Stack Overflow用户
提问于 2015-02-14 18:16:11
回答 1查看 2.2K关注 0票数 1

我有这个密码。为了让它发挥作用,我不得不使用Args&&.而不是Args..。或者Args&..。我注意到args从&到const&或&& to &。Args到底是怎么回事..。Args&..。还有Args&.?

当签名是Args..

代码语言:javascript
复制
template<class V, class F, class... Args> void
Parse(int n, V& v, const F& f, Args... args) 

解析(20150201,y,4,m,2,d,2)只填充y=2015。

在调试函数的第一个递归时,我看到了以下内容:

代码语言:javascript
复制
f      4 const int&
v      0 int&
args_0 2 int
args_1 0 int         <-- needs to be int&
args_2 2 int
args_3 0 int         <-- needs to be int&

第二次迭代如下所示:

代码语言:javascript
复制
f      4 const int&
v      0 int&        <-- this refs the int on the first level, not m
args_0 2 int          
args_1 0 int         <-- needs to be int&

第三次迭代如下所示:

代码语言:javascript
复制
f      4 const int&
v      0 int&        <-- this refs the int on the 2nd level, not d

这样就不管用了。

时签名为Args&.:

代码语言:javascript
复制
template<class V, class F, class... Args> void
Parse(int n, V& v, const F& f, Args&... args) 

解析(20150201,y,4,m,2,d,2)产生了这个编译器错误。

代码语言:javascript
复制
Variadac.cpp(360): error C2664: 'void Parse<int,int,int,int,int,int>(int,V &,const F &,int &,int &,int &,int&)' : cannot convert argument 5 from 'int' to 'int &' with [V=int,F=int]

我想'2‘不可能是整数。

时签名为Args&&.:

代码语言:javascript
复制
template<class V, class F, class... Args> void
Parse(int n, V& v, const F& f, Args&&... args) 

解析(20150201,y,4,m,2,d,2)将填充正确的y=2015、m=2、d=1。

在调试函数的第一个递归时,我看到了以下内容:

代码语言:javascript
复制
f      4 const int&
v      0 int&
args_0 2 int&
args_1 0 int&&
args_2 2 int&
args_3 0 int&&

第二次迭代如下所示:

代码语言:javascript
复制
f      4 const int&
v      0 int&        <-- hey! this was int &&
args_0 2 int&          
args_1 0 int&        <-- hey! this was int &&

第三次迭代如下所示:

代码语言:javascript
复制
f      4 const int&
v      0 int&        

int&&正与一些参数一起使用,而int& &与其他参数一起使用。

这是密码。它试图成为一个通用的解析器,从一个整数中提取不同的数字片段。

代码语言:javascript
复制
int Pow(const int n) {
    switch (n) {
    case 1: return 10;
    case 2: return 100;
    case 3: return 1000;
    case 4: return 10000;
    case 5: return 100000;
    case 6: return 1000000;
    case 7: return 10000000;
    case 8: return 100000000;
    case 9: return 1000000000;
    }
}

template<class V, class F, class... Args> int
Pow(V& v, const F& f, Args... args) {
    return Pow(f) * Pow(args...);
}
template<class V, class F> int
Pow(V& v, const F& f) {
    return Pow(f);
}

// Parse(1234, a, 2, b, 2)
template<class V, class F, class... Args> void
Parse(int n, V& v, const F& f, Args&&... args) {
    const int p = Pow(args...);
    v = n / p;
    Parse(n % p, args...);
}
// Parse(100, n, 3)
template<class V, class F> INL void
Parse(int n, V& v, const F& f) {
    v = n;
}

int main(int argc, char* argv[])
{
    int y, m, d;
    Parse(20150210+argc, y, 4, m, 2, d, 2);
    return y + m + d;
}

我对这段代码很满意,因为它似乎解开了循环,并产生了循环自由程序集。我不知道这是否是一个很好的程序集,我也没有描述过不同的数字提取方法(现在我使用的是n%p,它在其他领域的轮廓比n*p更好)。在表面上,看起来所有的除法和模数都是由编译时间推导出来的。

代码语言:javascript
复制
    Parse(20150210+argc, y, 4, m, 2, d, 2);
000000013F9C3274  imul        esi  
000000013F9C3276  mov         edi,edx  
000000013F9C3278  sar         edi,0Ch  
000000013F9C327B  mov         eax,edi  
000000013F9C327D  shr         eax,1Fh  
000000013F9C3280  add         edi,eax  
000000013F9C3282  imul        eax,edi,2710h  
000000013F9C3288  sub         esi,eax  
000000013F9C328A  mov         eax,51EB851Fh  
000000013F9C328F  imul        esi  
000000013F9C3291  mov         ebx,edx  
000000013F9C3293  sar         ebx,5  
000000013F9C3296  mov         eax,ebx  
000000013F9C3298  shr         eax,1Fh  
000000013F9C329B  add         ebx,eax  
000000013F9C329D  imul        eax,ebx,64h  
000000013F9C32A0  sub         esi,eax  
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-02-14 18:57:49

当使用表单T的参数推断模板参数T&&时,类型T将保留它是lvalue还是rvalue,以及lvalue的cv-限定符。如果将类型为X的对象传递给声明为

代码语言:javascript
复制
template <typename T> void f(T&& t);

您将得到以下类型:

  • f(X()) => T == X
  • X x; f(x) => T == X&
  • X const& xc; f(x) => T == X const&

无论这些论点是单独的还是通过各种不同的参数推导出来的,都没有任何区别。在f()中,参数t始终是一个lvalue,因为它有一个名称。因此,使用参数从f()调用函数不会认为参数是rvalue。如果要转发参数并保留其属性(如原始调用中的那样),则需要使用std::forward()

代码语言:javascript
复制
g(std::forward<T>(t));

std:: forward()的调用只会导致参数出现与原始模板的参数相同的类型。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28518693

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档