views:

285

answers:

2

I would like to write something like this, which cannot be compiled:

std::vector<A> as;
std::vector<B> bs( as.size() );
std::transform( as.beginn(), as.end(), bs.begin(), boost::lexical_cast<B> );

But this is not working, so I created a functor which is doing this for me:

template<typename Dest>
struct lexical_transform
{
    template<typename Src>
    Dest operator()( const Src& src ) const
    {
        return boost::lexical_cast<Dest>( src );
    }
};

Is there an easier way to do this?

+5  A: 

lexical_cast has two template arguments: target type and source type. Under normal usage, the second is deduced from the call.

However, here you want to take the address of the function, and you need to specify all the template arguments:

std::transform( as.begin(), as.end(), bs.begin(), boost::lexical_cast<B, A> );
UncleBens
thnx a lot, it works perfect
Rupert Jones
+1  A: 

If you do this kind of thing a lot you might want to consider the Boost.Convert library (not an accepted part of Boost yet). See this example from the manual:

std::transform(strings.begin(), strings.end(),
               std::back_inserter(integers),
               boost::convert<int>::from<string>());
Manuel
is there an advantage compared to the approach given by UncleBens?
Rupert Jones
Not really for your example for in general it gives your more power. For instance you can use IO manipulators like std::hex or specify a default value that is used in case the conversion is not possible
Manuel