简体   繁体   中英

How to fill vector with values returned by a member function in C++03?

I would like to get the same behavior as this:

IdentifiersGenerator gen;
for(int i = 0; i < 100; ++i)
  v.push_back(gen.getNextIdentifiers());

with syntax similar to:

IdentifiersGenerator gen;
std::vector<Identifiers> v(100);
std::generate(v.begin(), v.end(),
    std::bind1st(std::mem_fun(&IdentifiersGenerator::getNextIdentifiers), gen));

the above snippet gives the following error:

test/src/IdentifiersGeneratorTest.cpp:449:   instantiated from here
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/backward/binders.h:100: error: no type named ‘second_argument_type’ in ‘class std::mem_fun_t<const Identifiers&, IdentifiersGenerator>’
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/backward/binders.h:103: error: no type named ‘first_argument_type’ in ‘class std::mem_fun_t<const Identifiers&, IdentifiersGenerator>’
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/backward/binders.h:106: error: no type named ‘first_argument_type’ in ‘class std::mem_fun_t<const Identifiers&, IdentifiersGenerator>’
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/backward/binders.h:111: error: no type named ‘second_argument_type’ in ‘class std::mem_fun_t<const Identifiers&, IdentifiersGenerator>’
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/backward/binders.h:117: error: no type named ‘second_argument_type’ in ‘class std::mem_fun_t<const Identifiers&, IdentifiersGenerator>’
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/backward/binders.h: In function ‘std::binder1st<_Operation> std::bind1st(const _Operation&, const _Tp&) [with _Operation = std::mem_fun_t<const Identifiers&, IdentifiersGenerator>, _Tp = IdentifiersGenerator]’:
test/src/IdentifiersGeneratorTest.cpp:449:   instantiated from here
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/backward/binders.h:126: error: no type named ‘first_argument_type’ in ‘class std::mem_fun_t<const Identifiers&, IdentifiersGenerator>’

Maybe this can be done even without std::vector default object initialization using eg boost::make_function_input_iterator .

EDIT OK, so I have realized that I can use boost::bind like so:

std::vector<AlarmIdentifiers> v(100);
std::generate(v.begin(), v.end(),
    boost::bind(&IdentifiersGenerator::getNextIdentifiers, &gen));

Anyone can share an approach to initialize the vector with pointer to member function instead of constructing and then generating inside it?

The reason this doesn't work:

std::bind1st(std::mem_fun(&IdentifiersGenerator::getNextIdentifiers), gen)

is that bind1st requires a binary function whereas you are providing a unary one. There isn't a prepackaged C++03 solution to this, if boost::bind is an option I would just use that.

Otherwise, could write your own factory that takes a pointer to nullary member function and a pointer to the class and returns an object with operator() that invokes it.

(posting here just for reference)

OK, so I have realized that I can use boost::bind like so:

std::vector<AlarmIdentifiers> v(100);
std::generate(v.begin(), v.end(),
    boost::bind(&IdentifiersGenerator::getNextIdentifiers, &gen));

bind is really an 'old' and mostly obsolete way to achieve something similar to the much nicer lambda syntax.

IdentifiersGenerator gen;
std::vector<Identifiers> v(100);
std::generate(v.begin(), v.end(), [&](){ return gen.getNextIdentifiers(); });

you could also use generate_n

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM