I have many examples of the following code:
struct foo1
{
foo1(int ii = 0, int jj = 0)
{
this->ii = ii;
this->jj = jj;
}
int ii;
int jj;
};
struct foo2
{
foo2()
{
}
foo2(const foo1& f)
{
this->f = f;
}
foo1 f;
};
typedef std::vector< foo2 > foo_v;
typedef std::set< int > bar_s;
bar_s barSet;
barSet.insert(1); barSet.insert(2); barSet.insert(3);
barSet.insert(4); barSet.insert(5); barSet.insert(6);
...
foo_v fooVec;
for (bar_s::iterator b = barSet.begin(); b != barSet.end(); ++b)
fooVec.push_back(foo2(*b));
How can I improve the code where it's filling a new vector 开发者_Go百科of foo2?
I was thinking something along the lines of:
std::remove_copy_if(barSet.begin(), barSet.end(),
std::back_inserter(fooVec), ...)
but I'm struggling to find a way to bind the int
type to new instances of the foo2
struct.
Note:
std::copy(barSet.begin(), barSet.end(), std::back_inserter(fooVec));
gives me the following error:
Error 1 error C2679: binary '=' : no operator found which takes a right-hand operand of type 'int' (or there is no acceptable conversion)
std::copy(barSet.begin(), barSet.end(), std::back_inserter(fooVec));
int is convertable to `foo' (the only constructor can be called with one int argument and it is not explicit).
Error 1 error C2679: binary '=' : no operator found which takes a right-hand operand of type 'int' (or there is no acceptable conversion)
This is because foo2 can not be contstructed from int, only from foo1 and only one step of implicit conversion is allowed. You can you std::transform:
std::transform(barSet.begin(), barSet.end(),
std::back_inserter(fooVec),
boost::lambda::constructor<foo2>());
The boost::lambda::constructor() can be replaced with std::fun_ptr(makeFoo2):
foo2 makeFoo2(const foo& f) { return f; }
You can use the vector's constructor that takes a pair of iterators.
foo_v fooVec(barSet.begin(), barSet.end());
Given the constructors of foo
, int
is implicitly convertible to foo
.
精彩评论