I have kind of a weird issue and while trying to create a small example to post here on stackoverflow, I failed to reproduce. Hopefully, this will still ring a bell to somebody, or somebody has a good idea to dig further...
On my Mac, the below code compiles fine with gcc 4.9.2. I'm using g++ -std=c++11 test.cpp
. On some other Linux/Fedora machine with gcc 4.7.2, I get a compilation error. Not on the below test example, but on a more complicated problem. I'm, however, not allowed to post that here, and unable to see what exactly is different.
I did, however, find a way to make it compile, by simply trying lots of things. I hope somebody might see what is wrong from that hint.
The way I could get my program to compile was to change the lambda body from v.push_back...
into this->v.push_back...
Any idea why that could be??
The compilation error I'm seeing is:
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/bits/stl_vector.h:881:7: note:
void std::vector<_Tp, _Alloc>::push_back(const value_type&)
[with_Tp
=aggregate
;_Alloc = std::allocator<aggregate>
;std::vector<_Tp, _Alloc>::value_type
=aggregate
] <near match>
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/bits/stl_vector.h:881:7: note: no known conversion for implicit'this'
parameter from'const std::vector<aggregate>*'
to'std::vector<aggregate>*'
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/bits/stl_vector.h:899:7: note:void std::vector<_Tp, _Alloc>::push_back(std::vector<_Tp, _Alloc>::value_type&&
) [with_Tp
=aggregate
;_Alloc
=std::allocator<aggregate>
;std::vector<_Tp, _Alloc>::value_type
=aggregate
] <near match>
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/bits/stl_vector.h:899:7: note: no known conversion for argument 1 from'aggregate'
to'std::vector<aggregate>::value_type&&
{akaaggregate&&
}'
The following fails to compile on the Linux machine with gcc 4.7.2:
#include <vector>
#include <iostream>
#include <functional>
struct aggregate {
int foo;
char bar[2];
};
template<typename T>
class test {
private:
std::vector<aggregate> v;
std::function<void(aggregate&)> lambda;
public:
test() :
lambda([this] (aggregate& a) { v.push_back(a); })
{
v.reserve(8);
}
void execute() {
aggregate a{1, "x"};
lambda(a);
}
};
int main() {
test<int> t;
t.execute();
}
$ g++ -std=c++11 test.cpp test.cpp
In lambda function:
test.cpp:17:53: error: no matching function for call to'std::vector<aggregate>::push_back(aggregate&) const'
test.cpp:17:53: note: candidates are:
In file included from /usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/vector:65:0, from test.cpp:1:
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/bits/stl_vector.h:881:7: note:void std::vector<_Tp, _Alloc>::push_back(const value_type&)
[with_Tp
=aggregate
;_Alloc
=std::allocator<aggregate>
;std::vector<_Tp, _Alloc>::value_type
=aggregate
] <near match>
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/bits/stl_vector.h:881:7: note: no known conversion for implicit'this'
parameter from'const std::vector<aggregate>*'
to'std::vector<aggregate>*'
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/bits/stl_vector.h:899:7: note:void std::vector<_Tp, _Alloc>::push_back(std::vector<_Tp, _Alloc>::value_type&&)
[with_Tp
=aggregate
;_Alloc
=std::allocator<aggregate>
;std::vector<_Tp, _Alloc>::value_type
=aggregate
] <near match>
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/bits/stl_vector.h:899:7: note: no known conversion for argument 1 from'aggregate'
to'std::vector<aggregate>::value_type&&
{akaaggregate&&
}'
But works fine after changing v.push_back...
into this->v.push_back...
Might the above be a manifestation of this bug in GCC 4.7.2?
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54277
Bug 54277 - [4.7/4.8 regression] Template class member referred to with implicit this inside lambda is incorrectly const-qualified
This answer was reached in a comment thread and is being pulled up here for consideration as a possible answer. If nothing else, it's the closest I've found that explains what's going on and why this doesn't occur in the newer compilers.