- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有这个代码。为了让它工作,我必须使用 Args&&... 而不是 Args... 或 Args&... 我注意到 args 从 & 转换为 const& 或 && 转换为 &。 Args...Args&... 和 Args&&... 究竟是怎么回事!?
当签名是 Args..
template<class V, class F, class... Args> void
Parse(int n, V& v, const F& f, Args... args)
Parse(20150201, y,4, m,2, d, 2) 只会填充 y=2015。
在调试函数的第一个递归时,我看到了这个:
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&
第二次迭代看起来像这样:
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
所以它不起作用。
当签名为 Args&... 时:
template<class V, class F, class... Args> void
Parse(int n, V& v, const F& f, Args&... args)
Parse(20150201, y,4, m,2, d, 2) 产生了这个编译器错误。
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' 不能是 int&。
当签名为 Args&&... 时:
template<class V, class F, class... Args> void
Parse(int n, V& v, const F& f, Args&&... args)
Parse(20150201, y,4, m,2, d, 2) 将填充 y=2015, m=2, d=1,这是正确的。
在调试函数的第一个递归时,我看到了这个:
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&& 与一些参数一起使用,而 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;
}
我对这段代码很满意,因为它似乎解开了循环并产生了无循环的汇编。我不知道这是否是一个很好的程序集,而且我还没有分析不同的拉出数字的方法(现在我使用 n%p ,它在其他领域的分析比 n - v*p 更好)。从表面上看,所有除法和模数似乎都是编译时推导的。
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
最佳答案
当使用 T&&
形式的参数推导模板参数 T
时,类型 T
将保留它是左值还是右值以及左值的 cv 限定符。也就是说,如果您将 X
类型的对象传递给声明为
template <typename T> void f(T&& t);
您将获得以下类型:
f(X())
=> T == X
X x; f(x)
=> T == X&
X const& xc; f(x)
=> T == X 常量&
无论参数是单独推导还是通过可变参数推导都没有任何区别。在 f()
中,参数 t
始终是一个左值,因为它有一个名称。因此,使用参数从 f()
调用函数不会将参数视为右值。如果您想像在原始调用中一样转发参数并保留其属性,则需要使用 std::forward()
:
g(std::forward<T>(t));
调用 std::forward()
只会使参数看起来与原始模板的参数相同。
关于c++ - Args..., Args&..., Args&& 是怎么回事,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28518693/
我有这个代码。为了让它工作,我必须使用 Args&&... 而不是 Args... 或 Args&... 我注意到 args 从 & 转换为 const& 或 && 转换为 &。 Args...Arg
当我定义类时,我总是去 Class A(object): def __init__(self, arg): self.arg = arg def print_arg(s
假设我想定义两个 {Type} 类的变量。构造函数采用 1 个参数。下面两种方式是否完全等价(编译成相同的目标代码)? Type a(arg), b(arg); 和 Type a(arg); Type
(旁白:我是一名 Perl 程序员,正如您所知,这是我的第一个重要的 Java 程序。简单的术语将不胜感激。) 我有以下启动器作为编码工作: import java.lang.reflect.*; i
Math.nextUp(arg) 始终与 arg + Math.ulp(arg) 相同,还是我遗漏了什么? System.out.println( 0.5 + Math.ulp(0.5));
今天我在学习完美转发,我创建了这个代码示例 #include #include template auto toStdFun(Function&& fun, Args&&...ar
我想知道你会选择哪个选项? putStrLn (show randomNum) putStrLn $ show randomNum (putStrLn . show) randomNum 所有选项在语
我试图在 visual studio 2012 中编译一个库,它最初是用 c++ 为 visual studio 2015 编写的。我有一个错误说 'class' missing tag。 错误消息的
我在下面的代码中遇到了运行时异常ArrayIndexOutOfBoundException,行中: if ( args[0].equals("t") || args[0].equals("time")
我有以下代码 import React, { Component } from "react"; import { Accounts } from "meteor/accounts-base"; ex
这个问题已经有答案了: Difference between Arrays and 3 dots (Varargs) in java (3 个回答) 已关闭 5 年前。 受学校线性代数 I 和 II
所以我定义了一个函数: def getDistnace(self, strings, parentD, nodeName, nodeDistance): 我用它来调用: Node.getDistnac
这个问题在这里已经有了答案: subprocess.call() arguments ignored when using shell=True w/ list [duplicate] (2 个答案
我想将参数传递给 java 应用程序,但喜欢 linux 应用程序风格。 java 中的main 方法对所有参数使用一个String 数组。在 Linux 中,大多数应用程序接受如下参数:ls -l
这是我的代码片段 #include void change(int a[]){ printf("%p\n",&a); } int main(){
我需要使用 python 3.6 subprocess.run() 函数发出以下命令: gsettings set org.gnome.shell enabled-extensions "['appl
这两个函数是否有任何有意义的不同?有什么理由通常更喜欢一个而不是另一个吗? void foo(auto x, auto &... y) { /* ... */ } template void foo(
例如: def m(arg, ...args) { println "arg: $arg" println "args: $args" } m('arg', k:'v') 输出: ar
我对 Java 还很陌生。目前正在尝试将 args[] 中给出的文件名传递给此 FileReader,但当我编译时,它说找不到指定的文件。如果我对文件名进行硬编码,它就可以正常工作。这应该如何运作?
为什么这是一个语法错误??做这件事的合适方法是什么? >>> def f(*args, option=None): File "", line 1 def f(*args, option=
我是一名优秀的程序员,十分优秀!