如何传递operator<< for string作为参数?

时间:2017-01-04 06:38:50

标签: c++

我想做那样的事情:

vector<string> road_map;
// do some stuff
for_each(road_map.begin(), road_map.end(), bind(cout, &ostream::operator<<));

注意:我不想为此目的使用lambda,例如:

[](const string& str){ cout << str << endl; }

C ++编译器将为lambda创建辅助代码。这就是为什么我不想在这种情况下使用lambda。我想对于这样的问题有更轻量级的解决方案。当然,这并不重要,如果没有简单的解决方案我只会使用lambda。

2 个答案:

答案 0 :(得分:4)

此答案主要用于调查 df['T'].apply(lambda line: [line.split('[')[0],None] if line.count('[') else [None,line.split('(')[0].strip()] ).apply(pd.Series ).rename( columns={0:'Maker',1:'Model'} ).apply( lambda col: col.ffill() if col.name == 'Maker' else col).dropna( subset=['Model'] ).reset_index(drop=True) 声明。

您应该注意,没有成员函数C++ compiler will create aux code for lambda占用ostream::operator<<std::string标题中只定义了一个独立的函数opertator<<(std::ostream&,const std::string&)

我使用了gcc godbolt,你可以看到例子Live here

所以我使用lambda和使用std :: bind的版本

创建了一个版本

使用bind得到

<string>

和x86_64上的这个程序集

void funcBind(std::vector<std::string>& a) 
{
    using namespace std;
    using func_t = std::ostream&(*)(std::ostream&, const std::string&);
    func_t fptr = &operator<<; //select the right overload
    std::for_each(
        a.begin(),
        a.end(), 
        std::bind(
            fptr,
            std::ref(std::cout),
            std::placeholders::_1)
    );
}

用lambda得到:

        push    rbp
        push    rbx
        sub     rsp, 8
        mov     rbp, QWORD PTR [rdi+8]
        mov     rbx, QWORD PTR [rdi]
        cmp     rbx, rbp
        je      .L22
.L24:
        mov     rdx, QWORD PTR [rbx+8]
        mov     rsi, QWORD PTR [rbx]
        mov     edi, OFFSET FLAT:std::cout
        add     rbx, 32
        call    std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, long)
        cmp     rbp, rbx
        jne     .L24
.L22:
        add     rsp, 8
        pop     rbx
        pop     rbp
        ret

和这个程序集

void  funcLambda(std::vector<std::string>& a)  
{
  std::for_each(
    a.begin(),
    a.end(),
    [](const std::string& b){std::cout << b;});
}

所以你实际上看不到任何明显的优化启用水平

答案 1 :(得分:2)

您可以使用ostream_iterator生成输出。

#include <string>
#include <vector>
#include <iostream>
#include <algorithm>
#include <iterator>

int main()
{
    std::vector<std::string> road_map{"ab", "cde"};
    // do some stuff
    std::copy(road_map.begin(), road_map.end(),
              std::ostream_iterator<std::string>(std::cout, "\n"));
}