C++ Args…,Args&;怎么回事;。。。,Args&&;

C++ Args…,Args&;怎么回事;。。。,Args&&;,c++,metaprogramming,C++,Metaprogramming,我有这个密码。为了让它工作,我必须使用Args&&。。。而不是Args。。。或Args&。。。我注意到args从&转换为const&或&&to&。Args到底是怎么回事。。。Args&。。。还有Args&& 签名为Args时.. template<class V, class F, class... Args> void Parse(int n, V& v, const F& f, Args... args) 第二次迭代如下所示: f 4 const i

我有这个密码。为了让它工作,我必须使用Args&&。。。而不是Args。。。或Args&。。。我注意到args从&转换为const&或&&to&。Args到底是怎么回事。。。Args&。。。还有Args&&

签名为Args时..

template<class V, class F, class... Args> void
Parse(int n, V& v, const F& f, Args... args) 
第二次迭代如下所示:

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&
f      4 const int&
v      0 int&        <-- this refs the int on the 2nd level, not d
f      4 const int&
v      0 int&        <-- hey! this was int &&
args_0 2 int&          
args_1 0 int&        <-- hey! this was int &&
f      4 const int&
v      0 int&        
int&&用于某些参数,int&用于其他参数

这是代码。它试图成为整数中不同数字片段的通用解析器

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;
}

当使用形式为
T&
的参数推断模板参数
T
时,
T
类型将保留它是左值还是右值,以及左值的cv限定符。也就是说,如果将类型为
X
的对象传递给声明为

template <typename T> void f(T&& t);

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

引用折叠规则:
&&&
/
&&&&
/
&&
=
&
&&
&&。请参阅完美转发和转发引用。为什么它使用int&,int&&,int&,int&&而不是int&,int&&,int&&,int&&,int&&&?好的,逗号很难看到。&&&&&&&&&&&&&&&&&&&&&&&&&&&&&>&和&&&&=>&&因此右值的类型是T或T&&而左值的类型是T&。T&&或T&&&&=>T&&和T&&&=>T&“以及左值和右值的cv限定符?只有非类、非数组类型的PRValue会丢失其cv限定。T==X=>X&&T;T==X&=>X&&&=>X?解析(20150201,y,4,m,2,d,2)。y变成int&,4变成int&。要保留左值还是右值,它必须是&或&&-它不可能是&或什么都不是?当我使用args时,这样说安全吗。。。编译器正在std::forward中包装每个单独的arg?如下所示:std::forward(arg_0)。
T
的类型被推断为状态,并得到应用的
&
。如果一个
&
应用于一个引用类型,它就是collapes,即
X&&&
等同于
X&
。2.是的,没有比使用最终传递引用的东西更能推断左值/右值的方法了。3.否。在函数中,所有参数都被视为左值(它们有一个名称)。如果要转发lvaluence/rvaluence,则需要显式使用
std::forward(args)…
f      4 const int&
v      0 int&
args_0 2 int&
args_1 0 int&&
args_2 2 int&
args_3 0 int&&
f      4 const int&
v      0 int&        <-- hey! this was int &&
args_0 2 int&          
args_1 0 int&        <-- hey! this was int &&
f      4 const int&
v      0 int&        
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;
}
    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  
template <typename T> void f(T&& t);
g(std::forward<T>(t));