我需要使用-value=str1,str2,str3
解析像boost::program_options
这样的cmd。我发现exactly the same question但它不再起作用了(使用1.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;
}
错误讯息:
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.
答案 0 :(得分:4)
您必须使operator>>
可被发现。
因为它需要在std::istream&
的左侧操作,所以不能在“拥有”类中声明它;但作为一个自由函数,您需要使用命名空间查找,以便代码找到流操作符。
现在请注意,从名称空间boost::detail
内部(来自Boost Lexicalcast库)调用流操作符。
它使用参数依赖查找来选择重载。 ADL意味着与参数类型相关联的名称空间指示应该为候选运算符搜索哪些名称空间&gt;&gt; overloads.¹
这意味着查找将搜索名称空间std
(由于std::istream
参数)以及lli
(由于第二个参数类型)。请注意,如果任何参数 types 本身使用模板参数类型,则定义 的命名空间也包含在查找中。
如你所说,你可以解决这个问题
lli
命名空间内的重载: Live On Coliru ¹它适用于非操作员免费功能,但
答案 1 :(得分:0)
由于某些原因,如果我只删除命名空间lli并且它按预期工作,它可以被编译(没有上面的错误)。