首先,这个语法让我印象深刻,你可以考虑为它写一个语法。
这使您可以更灵活地添加逻辑/约束,并更直接地解析为您设想的 AST 类型。有关此示例,请参阅此答案:
我找到了一种相对简单的方法,以防您可以将临时数据类型更改为 std::vector<std::pair<std::string, T> >。
由于使用lexical_cast<> 进行转换,您可以读取任何可输入流的值类型。让std::pair 输入可流式处理:
namespace std {
template <typename V> static inline std::istream& operator>>(std::istream& is, std::pair<std::string, V>& into) {
char ch;
while (is >> ch && ch!='=') into.first += ch;
return is >> into.second;
}
}
现在,你可以做描述了:
desc.add_options()
("help", "produce help message")
("float,f", po::value<Floats>()->multitoken(), "add a float to the map")
("int,i", po::value<Ints>()->multitoken(), "add a int to the map")
("string,s", po::value<Strings>()->multitoken(), "add a string to the map")
;
让我们解析你的示例命令行
po::variables_map vm;
po::store(po::parse_command_line(argc, argv, desc, po::command_line_style::default_style), vm);
po::notify(vm);
并打印解析的结果:
po::variables_map vm;
po::store(po::parse_command_line(argc, argv, desc, po::command_line_style::default_style), vm);
po::notify(vm);
std::cout << "Floats:"; for (auto p : vm["float"].as<Floats>()) std::cout << " ['" << p.first << "' -> " << p.second << "]";
std::cout << "\nInts:"; for (auto p : vm["int"].as<Ints>()) std::cout << " ['" << p.first << "' -> " << p.second << "]";
std::cout << "\nStrings:"; for (auto p : vm["string"].as<Strings>()) std::cout << " ['" << p.first << "' -> " << p.second << "]";
Live On Coliru
#include <boost/program_options.hpp>
#include <boost/program_options/cmdline.hpp>
#include <boost/any.hpp>
#include <vector>
#include <iostream>
namespace po = boost::program_options;
using Floats = std::vector<std::pair<std::string, float>>;
using Ints = std::vector<std::pair<std::string, int>>;
using Strings = std::vector<std::pair<std::string, std::string>>;
namespace std {
template <typename V> static inline std::istream& operator>>(std::istream& is, std::pair<std::string, V>& into) {
char ch;
while (is >> ch && ch!='=') into.first += ch;
return is >> into.second;
}
}
int main(int argc, char** argv) {
po::options_description desc("Allowed options");
desc.add_options()
("help", "produce help message")
("float,f", po::value<Floats>()->multitoken(), "add a float to the map")
("int,i", po::value<Ints>()->multitoken(), "add a int to the map")
("string,s", po::value<Strings>()->multitoken(), "add a string to the map")
;
po::variables_map vm;
po::store(po::parse_command_line(argc, argv, desc, po::command_line_style::default_style), vm);
po::notify(vm);
std::cout << "Floats:"; for (auto p : vm["float"].as<Floats>()) std::cout << " ['" << p.first << "' -> " << p.second << "]";
std::cout << "\nInts:"; for (auto p : vm["int"].as<Ints>()) std::cout << " ['" << p.first << "' -> " << p.second << "]";
std::cout << "\nStrings:"; for (auto p : vm["string"].as<Strings>()) std::cout << " ['" << p.first << "' -> " << p.second << "]";
}
打印:
Floats: ['my_float' -> 3.1415]
Ints: ['my_int' -> 20]
Strings: ['my_string' -> foo]