Aurelius Aurelius - 4 days ago 7
C++ Question

Default value for vector valued boost::program_options

I have a boost::program_options option that successfully parses the desired input options into a vector, but I'm not seeing how to also give it a default value. Example:

base.add_options()
("vector_value",po::value<std::vector<double> >(&vecoption)->multitoken(),"description");


works fine to read values into vecoptions, and something like

base.add_options()
("int_value",po::value<int>(&intoption)->default_value(1),"description");


also works fine, but trying to give the vector argument a default value like in

base.add_options()
("vector_value",po::value<std::vector<double> >(&vecoption)->default_value(std::vector<double>{0,1,2}),"description");


gives a compiler error


error: static assertion failed: Source type is neither std::ostream`able nor std::wostream`able


How can I create a vector-valued float option with default values like {0,1,2}?

Answer

Problem caused by missed operator<< for ostream for the type std::vector<double>. This operator required to provide textual representation of your default value. In the boost\program_options\value_semantic.hpp header you can find a comment about this requirement:

/** Specifies default value, which will be used if none is explicitly specified. The type 'T' should provide operator<< for ostream. */

typed_value* default_value(const T& v)

To solve the problem you can specify operator<< like:

namespace std
{
  std::ostream& operator<<(std::ostream &os, const std::vector<double> &vec) 
  {    
    for (auto item : vec) 
    { 
      os << item << " "; 
    } 
    return os; 
  }
} 

Boost is able to resolve the operator<< if it's defined in the namespace std. In this case default parameter value can be specified like:

("vector_value", po::value<std::vector<double> >(&vecoption)->multitoken()->default_value(std::vector<double>{0, 1, 2}), "description");  

The other approach is to use method with explicit textual value specification:

("vector_value", po::value<std::vector<double> >(&vecoption)->multitoken()->default_value(std::vector<double>{0, 1, 2}, "0, 1, 2"), "description");
Comments