这可能是许多常见问题解答 - 而不是使用:
cat file | command
Run Code Online (Sandbox Code Playgroud)
(这被称为无用的猫),正确的方式应该是:
command < file
Run Code Online (Sandbox Code Playgroud)
在第二,"正确"的方式 - 操作系统不必产生额外的过程.
尽管知道这一点,我继续使用无用的猫有两个原因.
更美观 - 我喜欢数据仅从左到右均匀移动.而且它更容易更换cat别的东西(gzcat,echo,...),添加第二个文件或插入新的过滤器(pv,mbuffer,grep...).
我"觉得"在某些情况下可能会更快.更快,因为有2个进程,1st(cat)执行读取而第二个执行任何操作.它们可以并行运行,这意味着有时可以更快地执行.
我的逻辑是否正确(第二个原因)?
我想知道为什么std::accumulate(aka reduce)需要第三个参数.对于那些不知道是什么accumulate的人,它是这样使用的:
vector<int> V{1,2,3};
int sum = accumulate(V.begin(), V.end(), 0);
// sum == 6
Run Code Online (Sandbox Code Playgroud)
来电accumulate相当于:
sum = 0; // 0 - value of 3rd param
for (auto x : V) sum += x;
Run Code Online (Sandbox Code Playgroud)
还有可选的第4个参数,允许用任何其他操作替换添加.
我听过的理由是,如果你需要说不加,而是乘以向量的元素,我们需要其他(非零)初始值:
vector<int> V{1,2,3};
int product = accumulate(V.begin(), V.end(), 1, multiplies<int>());
Run Code Online (Sandbox Code Playgroud)
但是为什么不像Python一样 - 设置初始值V.begin(),并使用范围从开始V.begin()+1.像这样的东西:
int sum = accumulate(V.begin()+1, V.end(), V.begin());
Run Code Online (Sandbox Code Playgroud)
这适用于任何操作.为什么需要第三个参数?
我正在编写从其他库中包含很多功能和方法的库.为了避免复制返回值我正在这样应用std::forward:
template<class T>
T&& wrapper(T&& t) {
f(t); // t passed as lvalue
return std::forward<T>(t);
}
Run Code Online (Sandbox Code Playgroud)
f返回void并获取T&&(或超载值).包装器总是返回包装器的参数,返回值应该保留参数的值.我是不是真的需要使用std::forward的return?RVO会让它变得多余吗?它是参考(R或L)的事实是否是多余的?如果return不是最后一个函数语句(在some if中),是否需要它?
如果wrapper()应该返回void或者是有争议的T&&,因为调用者可以通过arg访问评估值(参考,R或L).但在我的情况下,我需要返回值,以便wrapper()可以在表达式中使用.
它可能与这个问题无关,但众所周知,函数f不会被窃取t,所以第一次使用std::forwardin f(std::forward<T>(t))是多余的,它被我删除了.
我写过小测试:https://gist.github.com/3910503
测试显示,返回未转发T- 确实在gcc48和clang32中创建了额外的副本与-O3(RVO没有启动).
此外,我无法从UB中获得不良行为:
auto&& tmp = wrapper(42);
Run Code Online (Sandbox Code Playgroud)
它没有证明任何原因,因为它是未定义的行为(如果它是UB).
为什么这不能用gcc48和clang32编译?
#include <type_traits>
template <int N>
struct S {
template<class T>
typename std::enable_if<N==1, int>::type
f(T t) {return 1;};
template<class T>
typename std::enable_if<N!=1, int>::type
f(T t) {return 2;};
};
int main() {
S<1> s1;
return s1.f(99);
}
Run Code Online (Sandbox Code Playgroud)
GCC错误:
/home/lvv/p/sto/test/t.cc:12:2: error: no type named ‘type’ in ‘struct enable_if<false, int>’
f(T t) {return 2;};
^
Run Code Online (Sandbox Code Playgroud)
CLANG错误:
/home/lvv/p/sto/test/t.cc:11:26: error: no type named 'type' in 'std::enable_if<false, int>'; 'enable_if' cannot be used to
disable this declaration
typename std::enable_if<N!=1, int>::type
^~~~
/home/lvv/p/sto/test/t.cc:16:7: note: in instantiation of template …Run Code Online (Sandbox Code Playgroud) 我想和之std::accumulate合作std::min.像这样的东西(不会编译):
vector<int> V{2,1,3};
cout << accumulate(V.begin()+1, V.end(), V.front(), std::min<int>);
Run Code Online (Sandbox Code Playgroud)
可能吗?是否可以不编写包装函数std::min?
我知道我可以用lambdas做到这一点:
vector<int> V{2,1,3};
cout << std::accumulate(
V.begin()+1, V.end(),
V.front(),
[](int a,int b){ return min(a,b);}
);
Run Code Online (Sandbox Code Playgroud)
而且我知道有std::min_element.我不是要找到min元素,我需要std::accumulate和我的库结合std::min(或::min),它允许像C++中的表达式一样进行函数编程.
我想在Xorg下输入希腊字母.在系统xcompose(/usr/share/X11/locale/en_US.UTF-8/Compose)中有一行:
<dead_greek> <a> : "?" U03B1 # GREEK SMALL LETTER ALPHA
Run Code Online (Sandbox Code Playgroud)
如何用美国键盘输入?我的地方是en_US.UTF-8.这把钥匙是什么<dead_greek>?
我今天接受了面试.并被问及复杂性std:set_intersection.当我回答时,我提到了这一点
O(N + M)
等于:
O(MAX(N,M))
我被告知这是不正确的.我试图表现出与以下方面的对等关系是不成功的:
O(0.5*(n + m))≤O(max(n,m))≤O(n + m)
我的问题是:我真的不对吗?
什么是在二进制图像上分离(计数)咖啡豆的适当算法?豆类可以触摸并部分重叠.
咖啡豆图片http://cmm.ensmp.fr/~beucher/ex2a.gif
我的工作实际上不是咖啡豆,但咖啡豆更容易描述.这是我计算所有现在的人并计算人们从超市监控视频中穿过一些想象线的任务中的子问题.我已经将移动的对象提取到二进制掩码中,现在我需要以某种方式将它们分开.
有人在评论中提到的两个有希望的算法:
Clang-3.2可以编译和代码按预期运行:
struct have_f { int f(int i) {return 10;} };
struct empty {};
template <class T>
struct outer {
T t;
// if T have f(), define outer_f()
template<class U=decltype(t.f(1))>
int outer_f(int i) { return t.f(i); }
};
int main() {
outer<have_f> o1;
outer<empty> o2;
// to silence unused var warning
return o1.outer_f(10) + sizeof(o2);
}
Run Code Online (Sandbox Code Playgroud)
任何版本的GCC拒绝:
t.cc:13:6: error: ‘struct empty’ has no member named ‘f’
int outer_f(int i) { return t.f(i); }
^
Run Code Online (Sandbox Code Playgroud)
谁是对的?Gcc还是Clang?
注意,有类似的问题,没有真正的答案.
什么时候 std::forward不需要?它用于包装内部函数参数,它是templated-rvalue(也就是说,它可以是lvalue或named-rvalue).像:
template<class T>
void outer(T&& t) {
inner(std::forward<T>(t));
}
Run Code Online (Sandbox Code Playgroud)
我猜一个案例是当内部函数参数按值传递时.还有其他情况吗?当我写std::begin(std::forward<Ct>(ct))Ct是模板化的rvalue-ref 时,我有这个问题.
编辑可能的重复
如果我没记错的话,这是第三次尝试将这个4岁的问题关闭,因为一些不了解这个问题的新手.
"使用前锋的好处?" 和"何时不使用带有r值的std :: forward?" 是非常不同的问题.首先介绍初学者的r值,然后讨论高级C++用户的完美转发.我是元模板库和lambda库的作者,他们不需要详细的基础知识描述.答案中的信息与其他问题有很大不同.