最近想找一个跨平台配置文件类。本来ACE下有一个ACE_Configuration_Heap可以用,感觉也不错。不过只是为了读一下配置文件就把整个ACE库链接进来未免有些小题大作,所以重新寻找。boost里有一个Program_options,在Introduction里写的是The program_options library allows program developers to obtain program options, that is (name, value) pairs from the user, via conventional methods such as command line and config file. 感觉应该能用,花了几个小时读了一下。
结果出乎我的意料,这个库的设计初衷应该是用来处理命令行参数的,处理配置文件可能只是一个衍生物。对命令行参数处理是不错,对配置文件的支持则让人沮丧。别的不说,单是看一看其配置文件的实例 multiple_sources.cfg,唉!连section都没有!
此文件在 BOOST_ROOT\libs\program_options\example\目录下,内容如下:
#
# Comment out this line to use hard-coded default value of 10
#
optimization = 1
include-path = /opt
如果是要处理命令行,这个类是比较好的。除去一些正常的支持外,还支持UNICODE,支持winmain参数等不少功能。但我想要的是一个处理配置文件的类,只得放手了。
不过这个库有些小技巧感觉还是不错的,下面这段代码如果是C++的初学者可能会很吃惊,因为这个集合加项的语法比较特别,让人感觉清晰明快。
怎么做到这样的效果?我简化了Program_options.add_options()相关的类和代码,有兴趣的朋友可以看一下。
测试代码
结果出乎我的意料,这个库的设计初衷应该是用来处理命令行参数的,处理配置文件可能只是一个衍生物。对命令行参数处理是不错,对配置文件的支持则让人沮丧。别的不说,单是看一看其配置文件的实例 multiple_sources.cfg,唉!连section都没有!
此文件在 BOOST_ROOT\libs\program_options\example\目录下,内容如下:
#
# Comment out this line to use hard-coded default value of 10
#
optimization = 1
include-path = /opt
如果是要处理命令行,这个类是比较好的。除去一些正常的支持外,还支持UNICODE,支持winmain参数等不少功能。但我想要的是一个处理配置文件的类,只得放手了。
不过这个库有些小技巧感觉还是不错的,下面这段代码如果是C++的初学者可能会很吃惊,因为这个集合加项的语法比较特别,让人感觉清晰明快。
namespace po = boost::program_options;
po::options_description generic("Generic options");
generic.add_options()
("version,v", "print version string")
("help", "produce help message") ;
po::options_description generic("Generic options");
generic.add_options()
("version,v", "print version string")
("help", "produce help message") ;
怎么做到这样的效果?我简化了Program_options.add_options()相关的类和代码,有兴趣的朋友可以看一下。
namespace demo
{
class option_description_demo
{
public:
option_description_demo(const char* name, const char* description):
_name(name), _description(description)
{
}
std::string name() {return _name;}
std::string description() {return _description;}
private:
std::string _name, _description;
};
class options_description_demo;
class options_description_easy_init_demo
{
public:
options_description_easy_init_demo(options_description_demo* owner): _owner(owner)
{
}
options_description_easy_init_demo& operator()(const char* name, const char* description);
private:
options_description_demo* _owner;
};
class options_description_demo
{
public:
void add(boost::shared_ptr<option_description_demo> desc)
{
_options.push_back(desc);
}
options_description_easy_init_demo add_options()
{
return options_description_easy_init_demo(this);
}
void show()
{
for(int i=0; i<_options.size(); ++i)
{
cout << "[" << _options[i]->name() << "] " << _options[i]->description() << endl;
}
}
private:
std::vector< boost::shared_ptr<option_description_demo> > _options;
};
options_description_easy_init_demo& options_description_easy_init_demo::operator()(const char* name, const char* description)
{
boost::shared_ptr<option_description_demo> item(new option_description_demo(name, description));
_owner->add(item);
return *this;
}
};
{
class option_description_demo
{
public:
option_description_demo(const char* name, const char* description):
_name(name), _description(description)
{
}
std::string name() {return _name;}
std::string description() {return _description;}
private:
std::string _name, _description;
};
class options_description_demo;
class options_description_easy_init_demo
{
public:
options_description_easy_init_demo(options_description_demo* owner): _owner(owner)
{
}
options_description_easy_init_demo& operator()(const char* name, const char* description);
private:
options_description_demo* _owner;
};
class options_description_demo
{
public:
void add(boost::shared_ptr<option_description_demo> desc)
{
_options.push_back(desc);
}
options_description_easy_init_demo add_options()
{
return options_description_easy_init_demo(this);
}
void show()
{
for(int i=0; i<_options.size(); ++i)
{
cout << "[" << _options[i]->name() << "] " << _options[i]->description() << endl;
}
}
private:
std::vector< boost::shared_ptr<option_description_demo> > _options;
};
options_description_easy_init_demo& options_description_easy_init_demo::operator()(const char* name, const char* description)
{
boost::shared_ptr<option_description_demo> item(new option_description_demo(name, description));
_owner->add(item);
return *this;
}
};
测试代码
demo::options_description_demo set;
set.add_options()
("name", "value")
("version", "print version string")
("help", "produce help message");
set.show();
set.add_options()
("name", "value")
("version", "print version string")
("help", "produce help message");
set.show();
结果:
/*
[name] value
[version] print version string
[help] produce help message */
[name] value
[version] print version string
[help] produce help message */