小编Gri*_*ngo的帖子

伪造插入器是一种好习惯吗?

我们被教导创建函数对象以使用算法.

有算法可以调用operator(),如:

  • 的for_each
  • find_if
  • 的remove_if
  • max_element
  • count_if

这些函数对象通常应该从函数,谓词等继承unary_functionbinary_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 …

c++ algorithm stl

16
推荐指数
2
解决办法
645
查看次数

如何在for_each中组合函数和谓词?

你怎么能叫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的算法并不是我应该做的事情.

  1. 有没有办法只使用现有的STL关键字来生成这个?

    希望做一个

     for_each( shapes.begin(), shapes.end(),
                       bind2nd( ptr_fun(display_shape_if_color_equals), 0 ) );
    
    Run Code Online (Sandbox Code Playgroud)

    因为,在一个更复杂的情况下,仿函数名称会对仿函数产生误导

  2. *有没有办法访问结构的成员(如colorEquals),for_each无需创建函数等功能?*

c++ stl

10
推荐指数
4
解决办法
8142
查看次数

使用共享库中的STL参数调用函数

我知道安全地导出函数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> >)

如何在导出功能时解决此类问题?

c++ shared-libraries

10
推荐指数
1
解决办法
1456
查看次数

调用std :: adjacent_difference()时的隐式转换

我想得到一个向量中相邻之间距离的向量:

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)

c++ stl

10
推荐指数
2
解决办法
1090
查看次数

如何检测对临时对象成员的引用

我的同事最近在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可执行文件没有崩溃.

我们的编译器都没有给出任何警告,因此我们现在担心代码中可能存在此错误.

虽然我们可以用grepc_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)

c++

9
推荐指数
1
解决办法
364
查看次数

你如何编写一个operator()或者比trivalue-compare-function更少的函子

为结构编写运算符<()似乎比编写经典的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)

c++ stl

8
推荐指数
2
解决办法
1979
查看次数

使用bind2nd()的奇怪的编译器错误:"已定义或声明的成员函数"而不是"引用引用"

在调用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++ templates compiler-errors bind2nd

8
推荐指数
1
解决办法
5196
查看次数

如何增加 Visual Studio 中“输出窗口”的缓冲区大小

我在启用“显示包含”选项的情况下构建 C++ 项目。

我想创建包含文件的图表,因此我复制了输出窗口的所有文本。然而,编译会产生如此多的行,以至于在达到一定限制后,它们就会被剪掉。

我注意到这个限制是 ~59 MB。

有没有办法增加这个限制,或者将其设置为无穷大?我至少可以将此输出直接重定向到文本文件中,而不是从输出窗口复制和粘贴文本吗?

visual-studio

6
推荐指数
1
解决办法
5193
查看次数

模拟conditional_back_inserter之类的东西的最好方法是什么?

我想用以下代码中的算法替换循环

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*的一个例子),但这并不提供可读性.

c++ stl

6
推荐指数
1
解决办法
435
查看次数

如何使用 STL 算法组合生成器

我有一个从容器条目生成组合的算法,我想找到最小化成本函数的组合:

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)

c++ c++20

6
推荐指数
1
解决办法
166
查看次数