我们被教导创建函数对象以使用算法.
有算法可以调用operator(),如:
这些函数对象通常应该从函数,谓词等继承unary_function或binary_function表现.
但书籍通常不会展示创建的示例OutputIterators:
例如,要遍历函数的输出
std::set_intersection(),我必须提供目标容器,然后遍历结果:
std::vector<int> tmp_dest;
std::set_difference (
src1.begin(), src1.end(),
src2.begin(), src2.end(),
std::back_inserter(tmp_dest));
std::for_each( tmp_dest.begin(), tmp_dest.end(), do_something );
int res = std::accumulate( tmp_dest.begin(), tmp_dest.end(), 0 );
Run Code Online (Sandbox Code Playgroud)
但是认为有时使用每个算法的值而不先存储它们会更有效,例如:
std::set_difference (
src1.begin(), src1.end(),
src2.begin(), src2.end(),
do_something );
Accumulator accumulate(0); // inherits from std::insert_iterator ?
std::set_difference (
src1.begin(), src1.end(),
src2.begin(), src2.end(),
accumulate );
Run Code Online (Sandbox Code Playgroud)
insert_iterator …你怎么能叫Function上一些容器的一部分,使用for_each()?
我已经创建了for_each_if()一个
for( i in shapes )
if( i.color == 1 )
displayShape(i);
Run Code Online (Sandbox Code Playgroud)
电话看起来像
for_each_if( shapes.begin(), shapes.end(),
bind2nd( ptr_fun(colorEquals), 0 ),
ptr_fun( displayShape ) );
bool colorEquals( Shape& s, int color ) {
return s.color == color;
}
Run Code Online (Sandbox Code Playgroud)
但是,我觉得模仿类似STL的算法并不是我应该做的事情.
有没有办法只使用现有的STL关键字来生成这个?
我不希望做一个
for_each( shapes.begin(), shapes.end(),
bind2nd( ptr_fun(display_shape_if_color_equals), 0 ) );
Run Code Online (Sandbox Code Playgroud)
因为,在一个更复杂的情况下,仿函数名称会对仿函数产生误导
*有没有办法访问结构的成员(如colorEquals),for_each无需创建函数等功能?*
我知道安全地导出函数C++参数(例如STL字符串)是不可能的,因为C++没有指定标准的ABI.(我已经读过这个作为如何从共享库调用函数的答案?)
人们倾向于认为,如果您的库和程序都使用相同的编译器构建,那么这不是问题,但不幸的是,对于某些VC++编译器,这并不完全正确.
Herb Sutter和Alexandrescu在"C++编码标准"中建议依赖于可移植类型(例如内置类型)而不是一个需要的函数string.
即代替std::string在模块界面中使用
std::string Translate( const std::string & );
Run Code Online (Sandbox Code Playgroud)
用一个
void Translate( const char *src, char* dest, size_t destSize );
Run Code Online (Sandbox Code Playgroud)
尽管他们认为这对于呼叫者和被呼叫者来说都相当复杂,但他们并没有提出更好的选择.
如何很好地传递更复杂的对象,例如std::map使用低级类型?(更不用说复杂的东西了map<string,vector<something_complex> >)
如何在导出功能时解决此类问题?
我想得到一个向量中相邻点之间距离的向量:
struct Point { double x, y, z; }
vector<double> adjacent_distances( vector<Point> points ) {
...
}
Run Code Online (Sandbox Code Playgroud)
stl::adjacent_difference()如果我只提供一个找到2点之间距离的函数,我认为这对我来说会有所帮助:
double point_distance( Point a, Point b ) {
return magnitude(a-b); // implementation details are unimportant
}
Run Code Online (Sandbox Code Playgroud)
因此,我希望这会奏效,
vector<double> adjacent_distances( vector<Point> points )
{
vector<double> distances;
std::adjacent_difference( points.begin(), points.end(),
std::back_inserter(distances),
ptr_fun( point_distance ) );
return distances;
}
Run Code Online (Sandbox Code Playgroud)
只是为了找到它,input并且output向量必须是(实际上)相同类型,因为 adjacent_difference()调用
output[0] = input[0]; // forces input and output to be of same value_type
output[1] = op( …Run Code Online (Sandbox Code Playgroud) 我的同事最近在Windows中编译了我们的程序,并发现了这种错误:
std::string a = "hello ";
std::string b = "world";
const char *p = (a+b).c_str();
printf("%s\n", p);
Run Code Online (Sandbox Code Playgroud)
由于某种原因,我们的Linux可执行文件没有崩溃.
我们的编译器都没有给出任何警告,因此我们现在担心代码中可能存在此错误.
虽然我们可以用grep的c_str()发生,做一次视力检查,有一个可能也做了以下可能性:
struct I {
int num;
I() { num=0; }
};
struct X {
I *m;
X() { m = new I; }
~X() { delete m; }
I get() { return *m; } // version 1, or
I& get() { return *m; } // version 2
};
Run Code Online (Sandbox Code Playgroud)
并访问它像:
I& a = X().get(); // will get a …Run Code Online (Sandbox Code Playgroud) 为结构编写运算符<()似乎比编写经典的trivalue比较更清晰.
例如,对以下内容进行排序
struct S {
int val;
};
Run Code Online (Sandbox Code Playgroud)
你可以写一个运算符<()
bool operator< ( const S &l, const S &r ) {
return l.val < r.val;
}
Run Code Online (Sandbox Code Playgroud)
或者,三值函数(通常以下列方式)
int compare( const S &l, const S &r ) {
if( r.val > l.val ) return 1;
if( r.val < l.val ) return -1;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
前者更清晰,因此可以说代码质量更好.后者迫使你想到3个案例,这使代码变得复杂.
但是这个想法在更复杂的结构中有点欺骗:
struct S {
int x;
int y;
};
Run Code Online (Sandbox Code Playgroud)
以下是明确的,并且begginners倾向于这样写
bool operator< ( const S &l, const S &r ) …Run Code Online (Sandbox Code Playgroud) 在调用func()这段代码时,我最近花了很多时间来理解错误消息:
int main()
{
vector< vector<double> > v;
double sum = 0;
for_each( v.begin(), v.end(),
bind2nd( ptr_fun(func), &sum ) );
return 0;
}
Run Code Online (Sandbox Code Playgroud)
什么时候func()这样声明,代码编译得很好:
void func( vector<double> v, double *sum )
{
}
Run Code Online (Sandbox Code Playgroud)
当我使用这个声明(为了效率),我得到一个编译器错误:
void func( const vector<double> &v, double *sum )
{
}
Run Code Online (Sandbox Code Playgroud)
我期望看到的错误类似于引用引用错误,因为binder2nd的operator()的定义,
result_type operator()(const argument_type& _Left) const
Run Code Online (Sandbox Code Playgroud)
相反,令我惊讶的是,Visual C++(VS2012)编译器给我的错误是:
错误C2535:'void std :: binder2nd <_Fn2> :: operator()(const std :: vector <_Ty>&)const':已定义或声明的成员函数
我无法解读.
operator()是已经定义?我得到的完整错误是:
error C2535: 'void std::binder2nd<_Fn2>::operator …Run Code Online (Sandbox Code Playgroud) 我在启用“显示包含”选项的情况下构建 C++ 项目。
我想创建包含文件的图表,因此我复制了输出窗口的所有文本。然而,编译会产生如此多的行,以至于在达到一定限制后,它们就会被剪掉。
我注意到这个限制是 ~59 MB。
有没有办法增加这个限制,或者将其设置为无穷大?我至少可以将此输出直接重定向到文本文件中,而不是从输出窗口复制和粘贴文本吗?
我想用以下代码中的算法替换循环
int numbers[] = { ... };
vector<int> output;
for( int* it = numbers+from; it != numbers+to ; ++it )
{
int square = func( *it );
if( predicate(square) )
{
output.push_back(square);
}
}
Run Code Online (Sandbox Code Playgroud)
该程序旨在转换值并在条件发生时将它们复制到目标.
std::copy_if因为那不会应用转换.std::transform因为缺少谓词transform_copy_if()由于转换变量的中间副本,编写a甚至不是一个好主意.看起来我唯一的希望就是创造一个conditional_back_insert_iterator.然后我可以有一个相当不错的电话,如:
int numbers[] = { ... };
vector<int> output;
std::transform(numbers+from, numbers+to,
conditional_back_inserter(predicate, output),
func);
Run Code Online (Sandbox Code Playgroud)
这种解决方案是治疗此类病例的最佳方法吗?我甚至无法谷歌条件插入器,所以我担心我走错了路.
我还可以想象我可以实现替代解决方案,例如
std::copy_if( transform_iterator<func>(numbers+from),
transform_iterator<func>(numbers+to),
back_inserter(output) );
Run Code Online (Sandbox Code Playgroud)
(这让我想起了boost中的*filter_iterators*的一个例子),但这并不提供可读性.
我有一个从容器条目生成组合的算法,我想找到最小化成本函数的组合:
struct Vec { double x; double y; };
double cost( Vec a, Vec b ) {
double dx = a.x - b.x;
double dy = a.y - b.y;
return dx*dx + dy*dy;
}
pair<Vec,Vec> get_pair_with_minimum_cost ( vector<Vec> inp, double (*cost_fun)(Vec,Vec) )
{
pair<Vec,Vec> result;
double min_cost = FLT_MAX;
size_t sz = inp.size();
for(size_t i=0; i<sz; i++) {
for (size_t j=i; j<sz; j++) {
double cost = cost_fun(inp[i], inp[j]);
if (cost < min_cost) {
min_cost = cost;
result = make_pair(inp[i], …Run Code Online (Sandbox Code Playgroud)