如何使用boost::program_选项解析逗号分隔的值?

如何使用boost::program_选项解析逗号分隔的值?,boost,command-line,boost-program-options,Boost,Command Line,Boost Program Options,我需要使用boost::program\u options解析cmd,比如-value=str1、str2、str3。我已经找到了,但它不再工作了(Boost1.55和1.56) 我尝试定义自己的类和映射器,但没有成功: namespace po = boost::program_options; desc.add_options() ("mattr", po::value<lli::CommaSeparatedVector>(&MAttrs), "Targ

我需要使用
boost::program\u options
解析cmd,比如
-value=str1、str2、str3
。我已经找到了,但它不再工作了(Boost1.55和1.56)

我尝试定义自己的类和映射器,但没有成功:

namespace po = boost::program_options;

desc.add_options()
        ("mattr", po::value<lli::CommaSeparatedVector>(&MAttrs), "Target specific attributes (-mattr=help for details)");

namespace lli {
  class CommaSeparatedVector 
  {
      public:
        // comma separated values list
        std::vector<std::string> values;
  };
}

void tokenize(const std::string& str, std::vector<std::string>& tokens, const std::string& delimiters = ",")
{
  // Skip delimiters at beginning.
  std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);

  // Find first non-delimiter.
  std::string::size_type pos = str.find_first_of(delimiters, lastPos);

  while (std::string::npos != pos || std::string::npos != lastPos) {
    // Found a token, add it to the vector.
    tokens.push_back(str.substr(lastPos, pos - lastPos));

    // Skip delimiters.
    lastPos = str.find_first_not_of(delimiters, pos);

    // Find next non-delimiter.
    pos = str.find_first_of(delimiters, lastPos);
  }
}

// mapper for "lli::CommaSeparatedVector"
std::istream& operator>>(std::istream& in, lli::CommaSeparatedVector &value)
{
    std::string token;
    in >> token;

    tokenize(token, value.values);

    return in;
}
namespace po=boost::program\u选项;
说明添加选项()
(“mattr”,po::value(&mattr),“特定于目标的属性(-mattr=详细信息帮助)”;
名称空间lli{
类逗号分离向量
{
公众:
//逗号分隔值列表
std::向量值;
};
}
void标记化(const std::string&str,std::vector&tokens,const std::string&delimiters=“,”)
{
//跳过开头的分隔符。
std::string::size\u type lastPos=str.find\u first\u not\u of(分隔符,0);
//查找第一个非分隔符。
std::string::size\u type pos=str.find\u first\u of(分隔符,lastPos);
while(std::string::npos!=pos | | std::string::npos!=lastPos){
//找到一个标记,将其添加到向量。
回推(str.substr(lastPos,pos-lastPos));
//跳过分隔符。
lastPos=str.find_first_not_of(分隔符,pos);
//查找下一个非分隔符。
pos=str.find_first_of(分隔符,lastPos);
}
}
//“lli::CommaSeparatedVector”的映射程序
std::istream和运算符>>(std::istream和in,lli::CommaseParated向量和值)
{
字符串标记;
在>>令牌中;
标记化(标记、值、值);
返回;
}
错误消息:

In file included from /softdev/boost-1.56/include/boost/program_options.hpp:15:
In file included from /softdev/boost-1.56/include/boost/program_options/options_description.hpp:13:
In file included from /softdev/boost-1.56/include/boost/program_options/value_semantic.hpp:14:
/softdev/boost-1.56/include/boost/lexical_cast.hpp:379:13: error: implicit instantiation of undefined template
      'boost::STATIC_ASSERTION_FAILURE<false>'
            BOOST_STATIC_ASSERT_MSG((result_t::value || boost::has_right_shift<std::basic_istream<wchar_t>, T >::value), 
            ^
/softdev/boost-1.56/include/boost/static_assert.hpp:36:48: note: expanded from macro 'BOOST_STATIC_ASSERT_MSG'
#     define BOOST_STATIC_ASSERT_MSG( B, Msg ) BOOST_STATIC_ASSERT( B )
                                               ^
/softdev/boost-1.56/include/boost/static_assert.hpp:169:13: note: expanded from macro 'BOOST_STATIC_ASSERT'
            sizeof(::boost::STATIC_ASSERTION_FAILURE< BOOST_STATIC_ASSERT_BOOL_CAST( __VA_ARGS__ ) >)>\
            ^
/softdev/boost-1.56/include/boost/lexical_cast.hpp:406:44: note: in instantiation of template class
      'boost::detail::deduce_target_char_impl<boost::detail::deduce_character_type_later<lli::CommaSeparatedVector> >'
      requested here
            typedef BOOST_DEDUCED_TYPENAME deduce_target_char_impl< stage1_type >::type stage2_type;
                                           ^
/softdev/boost-1.56/include/boost/lexical_cast.hpp:564:59: note: in instantiation of template class
      'boost::detail::deduce_target_char<lli::CommaSeparatedVector>' requested here
            typedef BOOST_DEDUCED_TYPENAME boost::detail::deduce_target_char<Target>::type target_char_t;
                                                          ^
/softdev/boost-1.56/include/boost/lexical_cast.hpp:2067:40: note: in instantiation of template class
      'boost::detail::lexical_cast_stream_traits<std::__1::basic_string<char>, lli::CommaSeparatedVector>' requested here
                BOOST_DEDUCED_TYPENAME stream_trait::char_type,
                                       ^
/softdev/boost-1.56/include/boost/lexical_cast.hpp:2289:20: note: in instantiation of template class
      'boost::detail::lexical_converter_impl<lli::CommaSeparatedVector, std::__1::basic_string<char> >' requested here
            return caster_type::try_convert(arg, result);
                   ^
/softdev/boost-1.56/include/boost/lexical_cast.hpp:2316:41: note: in instantiation of function template specialization
      'boost::conversion::detail::try_lexical_convert<lli::CommaSeparatedVector, std::__1::basic_string<char> >' requested
      here
        if (!boost::conversion::detail::try_lexical_convert(arg, result))
                                        ^
/softdev/boost-1.56/include/boost/program_options/detail/value_semantic.hpp:89:21: note: in instantiation of function
      template specialization 'boost::lexical_cast<lli::CommaSeparatedVector, std::__1::basic_string<char> >' requested here
            v = any(lexical_cast<T>(s));
                    ^
/softdev/boost-1.56/include/boost/program_options/detail/value_semantic.hpp:167:13: note: in instantiation of function
      template specialization 'boost::program_options::validate<lli::CommaSeparatedVector, char>' requested here
            validate(value_store, new_tokens, (T*)0, 0);
            ^
/softdev/boost-1.56/include/boost/program_options/detail/value_semantic.hpp:182:33: note: in instantiation of member function
      'boost::program_options::typed_value<lli::CommaSeparatedVector, char>::xparse' requested here
        typed_value<T>* r = new typed_value<T>(v);
                                ^
./lib_lli.cpp:480:23: note: in instantiation of function template specialization
      'boost::program_options::value<lli::CommaSeparatedVector>' requested here
        ("mattr", po::value<lli::CommaSeparatedVector>(&MAttrs), "Target specific attributes (-mattr=help for details)");
                      ^
/softdev/boost-1.56/include/boost/static_assert.hpp:87:26: note: template is declared here
template <bool x> struct STATIC_ASSERTION_FAILURE;
                         ^
1 warning and 1 error generated.
包含在/softdev/boost-1.56/include/boost/program_options.hpp:15中的文件中:
在/softdev/boost-1.56/include/boost/program_options/options_description包含的文件中。hpp:13:
在/softdev/boost-1.56/include/boost/program_options/value_semantic.hpp:14中包含的文件中:
/softdev/boost-1.56/include/boost/lexical_cast.hpp:379:13:错误:未定义模板的隐式实例化
'boost::静态\u断言\u失败'
BOOST_STATIC_ASSERT_MSG((result_t::value | | BOOST::has_right_shift::value),
^
/softdev/boost-1.56/include/boost/static\u assert.hpp:36:48:注意:从宏“boost\u static\u assert\u MSG”展开
#定义BOOST\u STATIC\u ASSERT\u MSG(B,MSG)BOOST\u STATIC\u ASSERT(B)
^
/softdev/boost-1.56/include/boost/static\u assert.hpp:169:13:注意:从宏“boost\u static\u assert”展开
sizeof(::boost::STATIC\u ASSERTION\u FAILURE)>\
^
/softdev/boost-1.56/include/boost/lexical_cast.hpp:406:44:注意:在模板类的实例化中
'boost::detail::推断\u target\u char\u impl'
在此请求
typedef BOOST_deculated_TYPENAME deculated_target_char_impl:type stage2_type;
^
/softdev/boost-1.56/include/boost/lexical_cast.hpp:564:59:注意:在模板类的实例化中
此处请求“boost::detail::推断目标字符”
typedef BOOST_推导的TYPENAME BOOST::detail::推断的目标字符::type target_char\t;
^
/softdev/boost-1.56/include/boost/lexical_cast.hpp:2067:40:注意:在模板类的实例化中
此处请求“boost::detail::lexical\u cast\u stream\u traits”
BOOST\u导出的\u类型名称流\u特征::char\u类型,
^
/softdev/boost-1.56/include/boost/lexical_cast.hpp:2289:20:注意:在模板类的实例化中
此处请求“boost::detail::lexical\u converter\u impl”
返回caster\u type::try\u convert(arg,result);
^
/softdev/boost-1.56/include/boost/lexical_cast.hpp:2316:41:注意:在函数模板专门化的实例化中
请求“boost::conversion::detail::try\u lexical\u conversion”
在这里
如果(!boost::conversion::detail::try_lexical_conversion(arg,result))
^
/softdev/boost-1.56/include/boost/program\u options/detail/value\u semantic.hpp:89:21:注意:在函数的实例化中
此处请求模板专门化“boost::lexical\u cast”
v=任何(词汇投射);
^
/softdev/boost-1.56/include/boost/program\u options/detail/value\u semantic.hpp:167:13:注意:在函数的实例化中
此处请求模板专门化“boost::program\u options::validate”
验证(值存储,新令牌,(T*)0,0);
^
/softdev/boost-1.56/include/boost/program\u options/detail/value\u semantic.hpp:182:33:注意:在成员函数的实例化中
此处请求“boost::program\u options::typed\u value::xparse”
类型化_值*r=新类型化_值(v);
^
./lib_lli.cpp:480:23:注意:在函数模板专门化的实例化中
此处请求“boost::program_options::value”
(“mattr”,po::value(&mattr),“特定于目标的属性(-mattr=详细信息帮助)”;
^
/softdev/boost-1.56/include/boost/static_assert.hpp:87:26:注意:这里声明了模板
模板结构静态断言失败;
^
生成1个警告和1个错误。

出于某种原因,如果我只删除名称空间lli,它可以被编译(没有上述错误),并且它可以按预期工作。

您必须使
操作符>
可发现

因为它需要在
std::istream&
的左侧操作,所以不能在“owning”类中声明它;但是作为一个自由函数,您需要使用名称空间查找,以便代码找到流操作符

现在请注意,正在从名称空间
boost::detail
(来自boost-Lexicalcast库)中的某个地方调用流式操作符

它使用依赖于参数的查找来选择重载。ADL表示与参数类型关联的名称空间指示应在哪些名称空间中搜索候选运算符>>重载。ª