в пример (regex.cpp), автор библиотеки создал пользовательскую структуру (magic_number) и функцию проверки для этой структуры, чтобы показать, как пользовательская структура может быть интегрирована в параметры программы. Я последовал его примеру, чтобы создать функцию проверки для пользовательского класса (MyClass). Компилятор жалуется, что lexical_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;
}
Я также попытался внести минимальные изменения в 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)
{
}
РЕДАКТИРОВАТЬ: Это может относиться к пространствам имен.
После того, как я окружил функцию проверки 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;
}
С пространством имен и класс, и validate должны принадлежать одному пространству имен.
Других решений пока нет …