Swi*_*Pie 2 c++ stdbind c++11 c++14
以下代码对于C++ 14编译器是合法的
// g++ -std=c++14 -pedantic -pthread main.cpp
// output: 1 2 3 4 5 1 1 1
#include <algorithm>
#include <vector>
#include <functional>
#include <iterator>
#include <iostream>
int main()
{
std::vector<int> a = { 1, 2, 3, 2, 4, 5, 1, 1, 3, 5, 1, 5 }, b = { 2, 5, 5, 3 }, c;
std::copy_if(a.begin(), a.end(), std::back_inserter(c),
std::bind(std::less<>(), // this won't work in pre-C++14
std::bind(
std::count<std::vector<int>::iterator, int>,
std::bind(static_cast<std::vector<int>::iterator (std::vector<int>::*)()>(&std::vector<int>::begin), &c),
std::bind(static_cast<std::vector<int>::iterator (std::vector<int>::*)()>(&std::vector<int>::end), &c),
std::placeholders::_1
),
std::bind(
std::minus<>(), // this won't work in pre-C++14
std::bind(
std::count<std::vector<int>::iterator, int>,
a.begin(),
a.end(),
std::placeholders::_1
),
std::bind(
std::count<std::vector<int>::iterator, int>,
b.begin(),
b.end(),
std::placeholders::_1
)
)
)
);
std::copy(c.begin(), c.end(), std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
它意味着从向量a的元素创建向量c,排除那些与向量b中的元素的数量和值匹配的向量.例如,如果a包含三个2和b - 其中两个,则c中只有一个2.
a)如何使这个代码适应C++ 11?减少<>和minus <>参数的直观跳跃... :: difference_type不起作用,编译器消息也没有帮助
b)当前版本按顺序删除最后一个匹配.什么代码会删除第一场比赛?
真正的答案是不使用bind().使用lambda:
std::copy_if(a.begin(), a.end(), std::back_inserter(c), [&](int elem){
return std::count(c.begin(), c.end(), elem) <
std::count(a.begin(), a.end(), elem) - std::count(b.begin(), b.end(), elem);
});
Run Code Online (Sandbox Code Playgroud)
这远远比解决方案更短std::bind(),工作在C++ 11,并且远远更容易理解.而且我们也不必进行手动模板扣除.
我们也可以这样写:
std::copy_if(a.begin(), a.end(), std::back_inserter(c), [&](int& elem){
return std::count(&elem + 1, &a[a.size()], elem) >=
std::count(b.begin(), b.end(), elem);
});
Run Code Online (Sandbox Code Playgroud)
请注意,我现在正在elem参考.这也使得更容易看到如何实现建议的扩展删除第一个匹配.这只是改变其侧面的elem在a我们的比较:
std::copy_if(a.begin(), a.end(), std::back_inserter(c), [&](int& elem) {
return std::count(&a[0], &elem, elem) >=
std::count(b.begin(), b.end(), elem);
});
Run Code Online (Sandbox Code Playgroud)