compilation fails for nested boost::variant of fusion pairs - c++

Following code fails to compile on gcc 4.9.2 with boost 1.64:
#include <boost/fusion/support/pair.hpp>
#include <boost/mpl/int.hpp>
#include <boost/variant.hpp>
#include <string>
namespace bf = boost::fusion;
namespace bm = boost::mpl;
int
main(int argc, char** argv)
{
using L2_t = boost::variant<bf::pair<bm::int_<1>,char>>;
using L1_t = boost::variant<bf::pair<bm::int_<1>,L2_t>>;
L1_t result;
}
while I think, it's legal.
Error message starts with:
/home/vagrant/.conan/data/boost/1.64.0/conaned/master/package/b06f2a498643ee1d889c6aea8e0e21d3cac9f57c/include/boost/fusion/support/pair.hpp: In instantiation of ‘constexpr boost::fusion::pai
r<First, Second>::pair(const boost::fusion::pair<First, Second2>&) [with Second2 = boost::variant<boost::fusion::pair<mpl_::int_<1>, char> >; First = mpl_::int_<1>; Second = char]’: /home/vagrant/.conan/data/boost/1.64.0/conaned/master/package/b06f2a498643ee1d889c6aea8e0e21d3cac9f57c/include/boost/type_traits/is_constructible.hpp:33:45: required by substitution of ‘tem
plate<class T, class Arg, class> static boost::type_traits::yes_type boost::detail::is_constructible_imp::test1(int) [with T = boost::fusion::pair<mpl_::int_<1>, char>; Arg = const boost::fus
ion::pair<mpl_::int_<1>, boost::variant<boost::fusion::pair<mpl_::int_<1>, char> > >&; <template-parameter-1-3> = <missing>]’
Compilation succeeds when I change one of pair's key value to make them different.
How to solve this problem? I use those pair key values to serialize/deserialize, so having them same values on different levels is important for me.

As xaxxon said, this works starting with gcc 5.2.

Related

Saving references

Consider the following uncomplicated code:
#include <thread>
#include <utility>
#include <vector>
#include <atomic>
#include <queue>
#include <iostream>
#include <functional>
using namespace std;
template<class It, class Fun>
void parallel_for(size_t num_threads, It first, It end, const Fun& fun) {
std::queue<std::thread> ts;
for (It it = first; it != end; ++it) {
if (std::distance(first, it) % num_threads == 0) {
fun(*it);
} else {
if (ts.size() == num_threads-1) {
ts.front().join();
ts.pop();
}
ts.push(std::thread(fun, std::ref(*it)));
}
}
while (not ts.empty()) {
ts.front().join();
ts.pop();
}
}
int main() {
std::atomic_int counter = 1;
auto lam = [&counter](auto& vl) {
vl = std::pair(counter++, -1);
};
// The following usage of std::ref works okay:
pair<int, int> x;
auto blam = bind(lam, ref(x));
blam();
// Nevertheless, the next line fails:
// lam(ref(x));
// As well as the next two ones:
// vector<pair<int, int>> v = {{4, 2}};
// parallel_for(thread::hardware_concurrency(), begin(v), end(v), lam);
return 0;
}
GCC's error on the last two lines, in particular, is
In file included from ./src/csc_cpp/passing_lambdas.cpp:1:
/usr/include/c++/10/thread: In instantiation of ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = const main()::<lambda(auto:1&)>&; _Args = {std::reference_wrapper<std::pair<int, int> >}; <template-parameter-1-3> = void]’:
./src/csc_cpp/passing_lambdas.cpp:22:26: required from ‘void parallel_for(size_t, It, It, const Fun&) [with It = __gnu_cxx::__normal_iterator<std::pair<int, int>*, std::vector<std::pair<int, int> > >; Fun = main()::<lambda(auto:1&)>; size_t = long unsigned int]’
./src/csc_cpp/passing_lambdas.cpp:47:71: required from here
/usr/include/c++/10/thread:136:44: error: static assertion failed: std::thread arguments must be invocable after conversion to rvalues
136 | typename decay<_Args>::type...>::value,
| ^~~~~
I am sure this is a trivial matter, but I am anyway struggling to understand this. I think I have been following the available examples on std::thread::thread()'s intended use quite closely, but this does not compile. What am I doing wrong?
First, let me clarify, because I'm not sure if it's obvious: the trick behind std::ref is that it returns an object of type std::reference_wrapper<T>, so you can use the result as object, but the object is implicitly convertible to T&, so it can be substituted where T& is needed.
lam(ref(x)); fails because you use auto in lam. Compiler doesn't know that you want vl to be std::pair<int, int>&, it deduces from what it gets. std::ref returns a temporary of std::reference_wrapper<std::pair<int, int>>, which cannot be bound to non-const reference. Use explicit type in lambda and it compiles:
auto lam = [&counter](std::pair<int, int>& vl) {
vl = std::pair(counter++, -1);
};
lam(std::ref(x));
Alternatively, you can explicitly convert to std::pair<int, int>& using get() or static_cast
auto lam = [&counter](auto& vl) {
vl = std::pair(counter++, -1);
};
lam(std::ref(x).get());
lam(static_cast<std::pair<int, int>&>(std::ref(x)));
The second part with parallel_for has exactly the same issue, you pass rvalue of std::reference_wrapper to lam.
About
lam(ref(x));
x is an lvalue while the ref(x) is a temporary reference_wrapper. You can not grab a temporary with an lvalue reference in your lam through auto&.
for that line, you can simply use
lam(x);

Boost.TypeErasure: movable functor

Since std::function requires copy semantics and captured lambda cannot be converted to std::function, I try to define movable function using boost.TypeErasure. Everything is OK until move assign operator is required.
#include <boost/type_erasure/any.hpp>
#include <boost/type_erasure/constructible.hpp>
#include <boost/type_erasure/callable.hpp>
#include <boost/type_erasure/builtin.hpp>
#include <boost/mpl/vector.hpp>
namespace bte = boost::type_erasure;
namespace bm = boost::mpl;
using Foo = bte::any<
bm::vector<
bte::constructible<bte::_self(bte::_self&&)>,
bte::assignable<bte::_self, bte::_self&&>,
bte::destructible<>,
bte::callable<void()>
>
>;
int main()
{
Foo{[&]{}};
}
With gcc, the compile error is:
In file included from /usr/local/include/boost/type_erasure/detail/normalize.hpp:34,
from /usr/local/include/boost/type_erasure/any.hpp:36,
from main.cpp:1:
/usr/local/include/boost/type_erasure/builtin.hpp: In instantiation of 'static void boost::type_erasure::assignable<T, U>::apply(T&, const U&) [with T = main()::<lambda()>; U = main()::<lambda()>&&]':
/usr/local/include/boost/type_erasure/detail/instantiate.hpp:91:9: required from 'static void boost::type_erasure::detail::instantiate_concept4::apply(Concept*, Map*) [with Concept = boost::mpl::vector<boost::type_erasure::constructible<boost::type_erasure::_self(boost::type_erasure::_self&&)>, boost::type_erasure::assignable<boost::type_erasure::_self, boost::type_erasure::_self&&>, boost::type_erasure::destructible<>, boost::type_erasure::callable<void()> >; Map = boost::mpl::map1<boost::mpl::pair<boost::type_erasure::_self, main()::<lambda()> > >]'
/usr/local/include/boost/type_erasure/any.hpp:225:13: required from 'boost::type_erasure::any<Concept, T>::any(U&&) [with U = main()::<lambda()>; Concept = boost::mpl::vector<boost::type_erasure::constructible<boost::type_erasure::_self(boost::type_erasure::_self&&)>, boost::type_erasure::assignable<boost::type_erasure::_self, boost::type_erasure::_self&&>, boost::type_erasure::destructible<>, boost::type_erasure::callable<void()> >; T = boost::type_erasure::_self]'
main.cpp:21:14: required from here
/usr/local/include/boost/type_erasure/builtin.hpp:73:51: error: use of deleted function 'main()::<lambda()>& main()::<lambda()>::operator=(const main()::<lambda()>&)'
static void apply(T& dst, const U& src) { dst = src; }
~~~~^~~~~
main.cpp:21:11: note: a lambda closure type has a deleted copy assignment operator
Foo{[&]{}};
^
I don't understand why apply's argument is const. And what is the correct way?
Coliru link
Update:
I thought lambda is move-assignable. However, it seems wrong.

Refer to a function that is member of a class [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
So i have this spaghetti-code project which i'm trying to make object oriented. Pittily i have encountered errors that i didn't quite understand, so i tried creating minimalistic code that does throw the same errors and that doesn't.
So here is some minimalistic code that compiles:
(File named "ims.cpp")
#include <cstdio>
#include <ros/ros.h>
#include <visualization_msgs/Marker.h>
#include <visualization_msgs/InteractiveMarker.h>
#include <interactive_markers/interactive_marker_server.h>
#include <interactive_markers/menu_handler.h>
#include <rosbag/bag.h>
#include <rosbag/view.h>
#include <ros/param.h>
#include <fstream>
#include <cmath>
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string.hpp>
using namespace visualization_msgs;
using namespace geometry_msgs;
using namespace std;
using namespace boost;
boost::shared_ptr<interactive_markers::InteractiveMarkerServer> server;
void doNothing(const InteractiveMarkerFeedbackConstPtr &feedback){
}
void testServer(){
InteractiveMarker inter_marker;
inter_marker.header.frame_id = 1;
Point pos;
pos.x = 3;
pos.y = 3;
inter_marker.pose.position = pos;
inter_marker.scale = 2;
inter_marker.name = "testServer";
server->insert(inter_marker, &doNothing);
}
int main(){}
Explenation: this is a ROS (robot operating system) project, still i believe this is a general c++ issue so i didn't ask the question in their "ros::answers" forum. Please don't get confused by types, we'll get to the problem.
The function "interactive_markers::InteractiveMarkerServer.insert" requires a "visualization_msgs::InteractiveMarker &" and a function that has a parameter of type "InteractiveMarkerFeedbackConstPtr &", as provided.
see: http://docs.ros.org/jade/api/interactive_markers
/html/classinteractive__markers_1_1InteractiveMarkerServer.html
So a minimal code throwing my error would be one that simply doesn't have the required parameter in the "doNothing" function, like this:
(File named "ims.cpp")
#include <as above>
using namespace visualization_msgs;
using namespace geometry_msgs;
using namespace std;
using namespace boost;
boost::shared_ptr<interactive_markers::InteractiveMarkerServer> server;
void doNothing(){
}
void testServer(){
InteractiveMarker inter_marker;
inter_marker.header.frame_id = 1;
Point pos;
pos.x = 3;
pos.y = 3;
inter_marker.pose.position = pos;
inter_marker.scale = 2;
inter_marker.name = "testServer";
server->insert(inter_marker, &doNothing);
}
int main(){}
throwing the error:
In file included from /usr/include/boost/function/detail/maybe_include.hpp:18:0,
from /usr/include/boost/function/detail/function_iterate.hpp:14,
from /usr/include/boost/preprocessor/iteration/detail/iter/forward1.hpp:52,
from /usr/include/boost/function.hpp:64,
from /opt/ros/indigo/include/ros/forwards.h:40,
from /opt/ros/indigo/include/ros/common.h:37,
from /opt/ros/indigo/include/ros/ros.h:43,
from /home/ros/ros/src/robotrainer_editor/heika_beta/ims/src/ims.cpp:3:
/usr/include/boost/function/function_template.hpp: In instantiation of ‘static void boost::detail::function::void_function_invoker1<FunctionPtr, R, T0>::invoke(boost::detail::function::function_buffer&, T0) [with FunctionPtr = void (*)(); R = void; T0 = const boost::shared_ptr<const visualization_msgs::InteractiveMarkerFeedback_<std::allocator<void> > >&]’:
/usr/include/boost/function/function_template.hpp:934:38: required from ‘void boost::function1<R, T1>::assign_to(Functor) [with Functor = void (*)(); R = void; T0 = const boost::shared_ptr<const visualization_msgs::InteractiveMarkerFeedback_<std::allocator<void> > >&]’
/usr/include/boost/function/function_template.hpp:722:7: required from ‘boost::function1<R, T1>::function1(Functor, typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, int>::type) [with Functor = void (*)(); R = void; T0 = const boost::shared_ptr<const visualization_msgs::InteractiveMarkerFeedback_<std::allocator<void> > >&; typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, int>::type = int]’
/usr/include/boost/function/function_template.hpp:1069:16: required from ‘boost::function<R(T0)>::function(Functor, typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, int>::type) [with Functor = void (*)(); R = void; T0 = const boost::shared_ptr<const visualization_msgs::InteractiveMarkerFeedback_<std::allocator<void> > >&; typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, int>::type = int]’
/home/ros/ros/src/robotrainer_editor/heika_beta/ims/src/ims.cpp:40:42: required from here
/usr/include/boost/function/function_template.hpp:112:11: error: too many arguments to function
BOOST_FUNCTION_RETURN(f(BOOST_FUNCTION_ARGS));
Which makes sense, right? The function doesn't have the parameter required, so the compiler complains.
So NOW we get to the true issue: in an object oriented code, i have the same problem:
HEADER FILE
(File named "ims.h")
#include <cstdio>
#include <ros/ros.h>
#include <visualization_msgs/Marker.h>
#include <visualization_msgs/InteractiveMarker.h>
#include <interactive_markers/interactive_marker_server.h>
#include <interactive_markers/menu_handler.h>
#include <rosbag/bag.h>
#include <rosbag/view.h>
#include <ros/param.h>
#include <fstream>
#include <cmath>
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string.hpp>
using namespace visualization_msgs;
using namespace geometry_msgs;
using namespace std;
using namespace boost;
class IMS{
boost::shared_ptr<interactive_markers::InteractiveMarkerServer> server;
IMS();
void doNothing(const InteractiveMarkerFeedbackConstPtr &feedback);
void testServer();
int main();
};
CPP DECLARATION
(File named "ims.cpp")
#include <ims.h>
IMS::IMS(){}
void IMS::doNothing(const InteractiveMarkerFeedbackConstPtr &feedback){
}
void IMS::testServer(){
InteractiveMarker inter_marker;
inter_marker.header.frame_id = 1;
Point pos;
pos.x = 3;
pos.y = 3;
inter_marker.pose.position = pos;
inter_marker.scale = 2;
inter_marker.name = "testServer";
server->insert(inter_marker, &IMS::doNothing); //other options that didn't work either: doNothing);//*this->doNothing(const InteractiveMarkerFeedbackConstPtr &feedback));//*this->doNothing());//this->doNothing);//&this->doNothing);//&IMS::doNothing);//&doNothing);
}
int IMS::main(){}
throwing the error:
In file included from /usr/include/boost/function/detail/maybe_include.hpp:18:0,
from /usr/include/boost/function/detail/function_iterate.hpp:14,
from /usr/include/boost/preprocessor/iteration/detail/iter/forward1.hpp:52,
from /usr/include/boost/function.hpp:64,
from /opt/ros/indigo/include/ros/forwards.h:40,
from /opt/ros/indigo/include/ros/common.h:37,
from /opt/ros/indigo/include/ros/ros.h:43,
from /home/ros/ros/src/robotrainer_editor/heika_beta/ims/include/ims.h:3,
from /home/ros/ros/src/robotrainer_editor/heika_beta/ims/src/ims.cpp:1:
/usr/include/boost/function/function_template.hpp: In instantiation of ‘static void boost::detail::function::function_void_mem_invoker1<MemberPtr, R, T0>::invoke(boost::detail::function::function_buffer&, T0) [with MemberPtr = void (IMS::*)(const boost::shared_ptr<const visualization_msgs::InteractiveMarkerFeedback_<std::allocator<void> > >&); R = void; T0 = const boost::shared_ptr<const visualization_msgs::InteractiveMarkerFeedback_<std::allocator<void> > >&]’:
/usr/include/boost/function/function_template.hpp:934:38: required from ‘void boost::function1<R, T1>::assign_to(Functor) [with Functor = void (IMS::*)(const boost::shared_ptr<const visualization_msgs::InteractiveMarkerFeedback_<std::allocator<void> > >&); R = void; T0 = const boost::shared_ptr<const visualization_msgs::InteractiveMarkerFeedback_<std::allocator<void> > >&]’
/usr/include/boost/function/function_template.hpp:722:7: required from ‘boost::function1<R, T1>::function1(Functor, typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, int>::type) [with Functor = void (IMS::*)(const boost::shared_ptr<const visualization_msgs::InteractiveMarkerFeedback_<std::allocator<void> > >&); R = void; T0 = const boost::shared_ptr<const visualization_msgs::InteractiveMarkerFeedback_<std::allocator<void> > >&; typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, int>::type = int]’
/usr/include/boost/function/function_template.hpp:1069:16: required from ‘boost::function<R(T0)>::function(Functor, typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, int>::type) [with Functor = void (IMS::*)(const boost::shared_ptr<const visualization_msgs::InteractiveMarkerFeedback_<std::allocator<void> > >&); R = void; T0 = const boost::shared_ptr<const visualization_msgs::InteractiveMarkerFeedback_<std::allocator<void> > >&; typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, int>::type = int]’
/home/ros/ros/src/robotrainer_editor/heika_beta/ims/src/ims.cpp:19:47: required from here
/usr/include/boost/function/function_template.hpp:225:11: error: no match for call to ‘(boost::_mfi::mf1<void, IMS, const boost::shared_ptr<const visualization_msgs::InteractiveMarkerFeedback_<std::allocator<void> > >&>) (const boost::shared_ptr<const visualization_msgs::InteractiveMarkerFeedback_<std::allocator<void> > >&)’
BOOST_FUNCTION_RETURN(boost::mem_fn(*f)(BOOST_FUNCTION_ARGS));
Diagnosis:
a friend of mine actually allready diagnosed a plausible source of the problem: apperently the compiler reformats the code to this
void IMS::doNothing(IMS this, const InteractiveMarkerFeedbackConstPtr &feedback){
which of course leads to the error, as the parameter doesn't fit our expectations anymore.
So here is my request:
Is this diagnosis correct?
if yes: can it be workarounded and how?
else: what is the actual problem?
Thanks anyone who even reads this long thread entirely, and thank you in advance for your answers!
Solution (following a suggestion by "einpoklum")
The solution the most fitting for my concept was a lambda, creating a functiuon to wrap the malicious "this" parameter.
std::function nothing =
[this] (const InteractiveMarkerFeedbackConstPtr &feedback) {this->doNothing(feedback);};
server->insert(inter_marker, nothing);
Thank you and everyone who bothered reading the whole thread very much, sorry for my difficulties asking the question understandably.
Trying to cut through the mountains of text and venture an answer: I think (but am not certain) the problem is you trying to pass a (non-static) member function as though it were a free-standing function.
That should not work, since you can't call a member function "just like that" - it has to have an associated object. On the implementation level, that piece of code needs to be called with the address of an instance of the class to serve as the this object.
What you can do in these situations is:
Wrap your member functions using std::mem_fn to get a proper function, with an extra first argument being the instance, or
Use a lambda which instantiates an object somehow (or just takes an instance as a reference) and invokes that instance's method. The lambda itself will degenerate into a freestanding function whose pointer you can pass around.
Make the method static - if it doesn't actually use any instance-specific data.

Compile error using adjacent_difference

I'm trying to use adjacent_difference with two different iterator types. The functor I have created takes the type used by the InputIterator as parameters and returns the type used by the OutputIterator. I don't understand why the code I included doesn't compile:
In file included from /usr/include/c++/4.9/numeric:62:0,
from 4: /usr/include/c++/4.9/bits/stl_numeric.h: In instantiation of '_OutputIterator
std::adjacent_difference(_InputIterator, _InputIterator,
_OutputIterator, _BinaryOperation) [with _InputIterator = __gnu_cxx::__normal_iterator >; _OutputIterator = __gnu_cxx::__normal_iterator >; _BinaryOperation = {anonymous}::CheckOp]':
48:85: required from here
/usr/include/c++/4.9/bits/stl_numeric.h:374:17: error: cannot convert
'_ValueType {aka Test}' to 'float' in assignment
*__result = __value;
// Example program
#include <iostream>
#include <string>
#include <numeric>
#include <vector>
struct Test
{
float first;
float second;
};
namespace{
class CheckOp {
public:
float operator()(Test x, Test y) const
{
float a = x.first - y.first;
float b = x.second - y.second;
return a + b;
}
};
}
int main()
{
std::vector<Test> testVec;
Test test1;
test1.first = 5.5F;
test1.second = 6.5F;
testVec.push_back(test1);
Test test2;
test2.first = 2.5F;
test2.second = 8.5F;
testVec.push_back(test2);
Test test3;
test3.first = 9.4F;
test3.second = 7.8F;
testVec.push_back(test3);
CheckOp checkOP;
std::vector<float> resultVec(testVec.size());
std::adjacent_difference(testVec.begin(), testVec.end(), resultVec.begin(), checkOP);
}
Note the description of adjacent_difference (from cppreference):
First, creates an accumulator acc whose type is InputIt's value type, initializes it with *first, and assigns the result to *d_first.
This implies that the input and output sequences must have the same, or at least a compatible, type.

What's wrong of this use of boost::lambda::bind?

I'm trying to use boost::lambda::bind() to define a predicate that I pass to the find_if algorithm in Boost.Range. Specifically, I want to search a vector of structures to find the first entry where a particular member has a specified value. My example is as follows:
#include <boost/lambda/bind.hpp>
#include <boost/range/algorithm/find_if.hpp>
#include <vector>
using namespace std;
using namespace boost;
using namespace boost::lambda;
struct foo
{
string s;
int x;
};
int main()
{
// create list and add a couple entries
vector<foo> fooList;
foo f1 = {"abc", 1};
foo f2 = {"def", 2};
fooList.push_back(f1);
fooList.push_back(f2);
// search for a value with the desired member
// fails with a compile error!
range_iterator<vector<foo> > it = find_if(fooList, boost::lambda::bind(&foo::s, _1) == string("abc"));
return 0;
}
When I try to compile this (under gcc 4.7.2), I get the typical spew of template instantiation errors, indicating that there was no operator== found that is compatible with the type returned by bind() and a const char []. I've tried this with other types also, such as int, with the same result.
I must be missing some small detail of bind() usage, but I can't see it; it seems like this sort of thing should work based upon the documentation. Am I wrong there?
Edit: Here is the first part of the compiler output:
test.cc:24:92: error: no match for ‘operator==’ in ‘boost::lambda::bind(const Arg1&, const Arg2&) [with Arg1 = std::basic_string<char> foo::*; Arg2 = boost::lambda::lambda_functor<boost::lambda::placeholder<1> >; typename boost::lambda::detail::bind_tuple_mapper<const Arg1, const Arg2>::type = boost::tuples::tuple<std::basic_string<char> foo::* const, const boost::lambda::lambda_functor<boost::lambda::placeholder<1> >, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type>]((* & boost::lambda::{anonymous}::_1)) == "abc"’
Turns out that I wasn't including the required headers. It appears that <boost/lambda/bind.hpp> only brings in bind functionality, and the operator overloads for the resulting type are not included. If I add #include <boost/lambda/lambda.hpp> to the above, then it resolves the compiler error that I referenced. The final revised code (fixing another error in the type of the return value from find_if()) is as follows:
#include <boost/lambda/bind.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/range/algorithm/find_if.hpp>
#include <string>
#include <vector>
using namespace std;
using namespace boost;
using namespace boost::lambda;
struct foo
{
string s;
int x;
};
int main()
{
// create list and add a couple entries
vector<foo> fooList;
foo f1 = {"abc", 1};
foo f2 = {"def", 2};
fooList.push_back(f1);
fooList.push_back(f2);
// search for a value with the desired member
typename range_iterator<vector<foo> >::type it = find_if(fooList, bind(&foo::s, _1) == "abc");
return 0;
}