Reputation: 4512
I want to do something like that:
vector<string> road_map;
// do some stuff
for_each(road_map.begin(), road_map.end(), bind(cout, &ostream::operator<<));
Note: I don't want to use lambda for this purpose, like that:
[](const string& str){ cout << str << endl; }
C++ compiler will create aux code for lambda. That's why I don't want to use lambda in such case. I suppose that there is more lightweight solution for such problem. Of course it is not critical, if there is not simple solution I just will use lambda.
Upvotes: 0
Views: 85
Reputation: 8284
This answer is mainly used to investigate the C++ compiler will create aux code for lambda
claim.
You should note that there is no member function ostream::operator<<
taking a std::string
. There's only a free-standing function opertator<<(std::ostream&,const std::string&) defined in the <string>
header.
I used gcc godbolt, you can see the example Live here
So I made a version using a lambda and a version using std::bind:
With bind you get
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)
);
}
and this assembly on x86_64
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
and with a lambda you get:
void funcLambda(std::vector<std::string>& a)
{
std::for_each(
a.begin(),
a.end(),
[](const std::string& b){std::cout << b;});
}
and this assembly
push rbp
push rbx
sub rsp, 8
mov rbp, QWORD PTR [rdi+8]
mov rbx, QWORD PTR [rdi]
cmp rbx, rbp
je .L27
.L29:
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 .L29
.L27:
add rsp, 8
pop rbx
pop rbp
ret
so you don't actually see any difference with any appreciable level of optimization enable
Upvotes: 4
Reputation: 19940
You can use an ostream_iterator to generate the output.
#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"));
}
Upvotes: 2