Can*_*hiu 7 c++ command-line boost-program-options
在示例(regex.cpp)中,库的作者为此结构创建了自定义结构(magic_number)和验证函数,以显示如何将自定义结构集成到程序选项中.我按照他的例子为自定义类(MyClass)创建了一个验证函数.编译器抱怨lecical_cast不适用于MyClass.然后std::istream& operator>>(std::istream& in, MyClass& d),我实现,删除void validate(.., MyClass*, ..),代码编译.任何人都可以解释为什么这个例子不需要operator>>,而我的不需要validate?
编辑:
#include <MyLib/MyClass.h>
std::istream& operator>>(std::istream& in, MyClass& obj) {
// some code to populate obj
return in;
}
po::variables_map parseCommandLine(int argc, char* argv[]) {
po::options_description options("Options");
options.add_options()
("help", "produce help message")
("obj", po::value<MyClass>(), "")
;
po::variables_map vm;
store(po::command_line_parser(argc, argv)
.options(options).run(), vm);
notify(vm);
return vm;
}
int main(int argc, char* argv[]) {
try {
po::variables_map vm = parseCommandLine(argc, argv);
MyClass obj = vm["my"].as<MyClass>();
cout << obj << endl;
} catch(std::exception& e) {
cout << e.what() << "\n";
return 1;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我也尝试对regex.cpp进行最小的更改:
#include <MyLib/MyClass.h>编辑:添加validate.他们都没有解决编译器错误.
void validate(boost::any& v,
const std::vector<std::string>& values,
std::vector<MyClass>*, int)
{
}
void validate(boost::any& v,
const std::vector<std::string>& values,
MyClass*, long)
{
}
void validate(boost::any& v,
const std::vector<std::string>& values,
MyClass*, int)
{
}
Run Code Online (Sandbox Code Playgroud)
编辑:它可能与命名空间有关.
在我包围了验证函数之后namespace boost { namespace program_options { }},编译的代码没有重载op >>.如果将validate放入与MyClass相同的命名空间中,它也可以工作.有谁能解释一下?
您面临的基本问题是C++没有提供将字符串转换为任意用户对象的任何工具(我的意思是不编写任何代码).
为了解决这个问题,program_options提供了两种可能性:
operator>>,这是标准的C++方式,但它可能会影响其他一些领域(即你可能想要以特定的方式解析你的对象,除了命令行).在内部,boost::lexical_cast用于实现转换,如果op>>找不到则会抛出错误.validate特定于program_options但在选项管理之外没有影响的函数.我想它使用模板元编程来确定您是否已提供validate或默认为lexical_cast.
我无法帮助你为什么你的尝试validate失败,因为你没有提供它的代码.
这是一个工作示例:
#include <boost/program_options.hpp>
#include <vector>
#include <string>
namespace po = boost::program_options;
namespace lib {
class MyClass
{
public:
int a;
};
void validate(boost::any& v,
const std::vector<std::string>& values,
MyClass*, int)
{
po::validators::check_first_occurrence(v);
const string& s = po::validators::get_single_string(values);
v = boost::any(MyClass { boost::lexical_cast<int>(s) } );
}
}
po::variables_map parseCommandLine(int argc, char* argv[])
{
po::options_description options("Options");
options.add_options()
("help", "produce help message")
("obj", po::value<lib::MyClass>(), "")
;
po::variables_map vm;
store(po::command_line_parser(argc, argv)
.options(options).run(), vm);
notify(vm);
return vm;
}
int main(int argc, char* argv[])
{
try {
po::variables_map vm = parseCommandLine(argc, argv);
lib::MyClass obj = vm["obj"].as<lib::MyClass>();
cout << obj.a << endl;
} catch(std::exception& e) {
cout << e.what() << "\n";
return 1;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
使用命名空间,类和validate都必须属于同一个命名空间.
| 归档时间: |
|
| 查看次数: |
2397 次 |
| 最近记录: |