I have a template looking like this:
struct add_node_value_visitor : boost::static_visitor<>
{
add_node_value_visitor(){}
template &l开发者_开发技巧t;typename T>
void operator() ( const T& value) const
{
boost::lexical_cast<std::string, T>(value);
}
};
The problem I have is that the visitor is used inside a for loop iterating over a bunch of values, and the resulting string of values needs to be one string, currently this would produce a bunch of separate strings, which is not what I want, so to solve this problem I thought I'd add a function pointer to the ctor of this struct so that I can pass in a function to concatenate the resulting string of each loop iteration and create one string. Then if I want to use this struct where I do not need a concatenation, I can still do that. The question is whether I should use a function pointer or is it possible to do this with something like boost::lambda?
Or would boost::function be easier to use?
Something like this?
struct add_node_value_visitor : public boost::static_visitor<>
{
public:
typedef std::function<void(const std::string&)> concat_func_t;
add_node_value_visitor(const concat_func_t& concat) : concat_(concat){}
template <typename T>
void operator() ( const T& value) const
{
concat_(boost::lexical_cast<std::string, T>(value));
}
private:
concat_func_t concat_;
};
Why not performing the concatenation in place?
struct add_node_value_visitor : boost::static_visitor<>
{
std::ostringstream st;
template <typename T>
void operator() ( const T& value ) {
// change concatenation logic here if required (separators...)
st << value;
}
std::string const & str() const {
return st.str();
}
};
Perhaps a more general-purpose visitor would be in order, leaving it up to the caller what to do with the string representations.
#include <boost/variant.hpp>
#include <boost/lexical_cast.hpp>
#include <string>
#include <vector>
#include <iostream>
struct to_string : boost::static_visitor<std::string>
{
template <typename T>
std::string operator() ( const T& value) const
{
return boost::lexical_cast<std::string, T>(value);
}
};
int main()
{
std::vector<boost::variant<int, double> > vec;
vec.push_back(42);
vec.push_back(3.14);
std::string result;
for (size_t i = 0; i != vec.size(); ++i) {
result += boost::apply_visitor(to_string(), vec[i] ) + ' ';
}
std::cout << result;
}
精彩评论