我想说我想对整数选项进行特殊处理。根据文档,我必须编写自己的验证函数。考虑以下简短程序。
#include <iostream>
#include <vector>
#include <string>
#include <boost/program_options.hpp>
namespace po = boost::program_options;
namespace boost { namespace program_options {
template <class charT>
void validate(boost::any& v, const std::vector<std::basic_string<charT> >& xs, unsigned int*, int)
{
std::cout << "validate is redefined" << std::endl;
// do something else
}
}}
int main(int argc, char* argv[])
{
po::options_description cmdLineOptions;
po::variables_map vm;
unsigned int v;
const char* args[] = {"tst", "-k", "10"};
cmdLineOptions.add_options()
("key,k", po::value<unsigned int>(&v)->required())
;
po::store(po::command_line_parser(sizeof(args) / sizeof(args[0]), args).options(cmdLineOptions).run(), vm);
po::notify(vm);
std::cout << v << '\n';
return 0;
}
它完美适用于VS 2013并输出
validate is redefined
10
在GCC中,它永远不会进入验证功能。
证明:http://coliru.stacked-crooked.com/a/fd558ebf987a4bbe
如果我尝试使用自定义类型而不是unsigned int,GCC会尝试使用program_option中的验证,最终会出现大量错误。
我做错了什么?
答案 0 :(得分:1)
初步预感,请考虑使用
BOOST_STRONG_TYPEDEF(unsigned int, Unsigned);
仅在内置类型上自定义行为似乎是一个坏主意。
解决方案:它与部分订购有关。
如果您将重载移到boost::program_options
命名空间之外,它将开始工作(因为它不再与基本模板竞争)。
<强> Live On Coliru 强>
#include <iostream>
#include <vector>
#include <string>
#include <boost/any.hpp>
#include <boost/serialization/strong_typedef.hpp>
#include <boost/program_options.hpp>
BOOST_STRONG_TYPEDEF(unsigned, Unsigned)
template<class charT>
void validate(boost::any& v,
const std::vector< std::basic_string<charT> >& xs,
Unsigned* p, int)
{
std::cout << "validate is redefined" << std::endl;
// do something else
}
namespace po = boost::program_options;
int main()
{
po::options_description cmdLineOptions;
po::variables_map vm;
Unsigned v;
const char* args[] = {"tst", "-k", "10"};
cmdLineOptions.add_options()
("key,k", po::value<Unsigned>(&v)->required())
;
po::store(po::command_line_parser(sizeof(args) / sizeof(args[0]), args).options(cmdLineOptions).run(), vm);
po::notify(vm);
std::cout << v << '\n';
return 0;
}
原因很可能是MSVC着名的两阶段查找