C++ Args…,Args&;怎么回事;。。。,Args&&;
我有这个密码。为了让它工作,我必须使用Args&&。。。而不是Args。。。或Args&。。。我注意到args从&转换为const&或&&to&。Args到底是怎么回事。。。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
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));