c++ - boost program_options中vector <string>选项的拆分值

标签 c++ boost boost-program-options

我正在开发一个通过配置文件读取某些选项的应用程序。该代码使用boost program_options库读取选项。

应用程序代码具有一个类,该类执行以下与读取选项值有关的任务:
1)function1()-定义所有可能的有效选项。将它们添加到option_description对象。2)function2()-解析配置文件并填充variable_map对象。3)function3()-返回选项的值。此函数如下所示-

template<typename T>
T function3(string optName){
    try{return vm[optName].as<T>();}
    catch(exception& e){ //some error handling message}
}

现在选择类似的选项
vector_of_string_option=value1,value2,value3

为此,我将此选项添加到选项描述对象中,如下所示:
("vector_of_string_option", po::value<vector<string>>(), "vector string");

为此vm["vector_of_string_option"].as<vector<string>>()返回带有第一个元素的 vector -"value1,value2,value3"
我希望返回的值是一个包含3个值的 vector -{“value1”,“value2”,“value3”}。

由于function3()是该类中的模板函数,因此我无法为vector写一个专门的函数(使用boost::split可以将字符串分开)。

如果有一种方法,我将对 vector 使用相同的方法。

那么,有没有办法通过program_options固有地实现这一目标?或任何其他建议在我的代码中实现这一目标?

最佳答案

使用Boost Program Options的想法是使用多 token /合成选项。

让我们继续

1)function1() - defines all the possible options that are valid. Adds them to an option_description object.


auto function1() {
    po::options_description desc;
    for (auto opt : s_opts)
        desc.add_options()(opt, po::value<std::string>());
    desc.add_options()
        ("vector_of_string_option", po::value<VoS>()->multitoken()->composing(), "vector string")
        ;
    return desc;
}

到现在为止还挺好

2)function2() - parses the config file and populates the variable_map object.


auto function2(std::istream&& is) {
    auto d = function1();
    po::parsed_options parsed = po::parse_config_file(is, d, false);
    po::variables_map vm;
    po::store(parsed, vm);
    po::notify(vm);

    return vm;
}

仍然没有问题。

3)function3()-

returns the value of an option.This function looks like this -


template <typename T>
T function3(std::string optName, po::variables_map const& vm) {
    try {
        return vm[optName].as<T>();
    } catch (std::exception const& e) {
        std::cerr << "Whoops: " << e.what() << "\n";
        exit(1);
    }
}

好。
int main() {
    auto vm = function2(std::istringstream(R"(
bar=BARRRR
# bar=QUXXXX # "cannot be specified more than once"
vector_of_string_option=value1
vector_of_string_option=value2
vector_of_string_option=value3
)"));
    std::cout << function3<std::string>("bar", vm) << "\n";
    for (auto& v : function3<VoS>("vector_of_string_option", vm)) {
        std::cout << " - " << std::quoted(v) << "\n";
    }
}

打印品:
BARRRR
 - "value1"
 - "value2"
 - "value3"

I want the returned value to be a vector containing 3 values - {"value1" , "value2" , "value3"}.



已经完成,请查看 Live On Coliru

Since function3() is a templatized function in the class, I cannot write a specialized function for vector(that would split the string say, using boost::split).



你当然可以!您不能/部分/专门化,但是可以专门化:
template <>
VoS function3<VoS>(std::string optName, po::variables_map const& vm) {
    try {
        VoS result;
        auto const& raw = vm[optName].as<VoS>();

        using namespace boost::algorithm;
        for(auto& rv : raw) {
            VoS tmp;
            split(tmp, rv, is_any_of(",; "), token_compress_on);
            result.insert(result.end(), tmp.begin(), tmp.end());
        }
        return result;
    } catch (std::exception const& e) {
        std::cerr << "Whoops: " << e.what() << "\n";
        exit(1);
    }
}

这样一来,您就可以使用多个值,但也可以拆分每个值:
int main() {
    auto vm = function2(std::istringstream(R"(
bar=BARRRR
# bar=QUXXXX # "cannot be specified more than once"
vector_of_string_option=value1, value2, value3
vector_of_string_option=value4, value5, value6
)"));
    std::cout << function3<std::string>("bar", vm) << "\n";
    for (auto& v : function3<VoS>("vector_of_string_option", vm)) {
        std::cout << " - " << std::quoted(v) << "\n";
    }
}

版画
BARRRR
 - "value1"
 - "value2"
 - "value3"
 - "value4"
 - "value5"
 - "value6"

再次,看到它 Live On Coliru

额外奖励

如果您想要部分特化,则可以将function3的实现委派给模板类,或者使用标签分发。这样也可以轻松解析set<int>list<bool>

草案:http://coliru.stacked-crooked.com/a/7971dd671010d38e

关于c++ - boost program_options中vector <string>选项的拆分值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61778413/

相关文章:

c++ - 在 Boost.Log 中正确使用 asynchronous_sink::flush()

c++ - Boost 程序选项允许输入值集

c++ - 跳过未知选项而不抛出 boost 程序选项

c++ - 如何使用 boost 程序选项获取默认参数值?

c++ - 抽象类和多态性

c++ - 为什么 std::shared_ptr 没有 operator->*?

c++ - 如何在一行中递增对值的同时初始化对 vector C++

c++ - QVariantList追加

c++ - 我应该使用 Boost.Test 分别测试不同的类吗?

c++ - boost `less_than` 两种版本的实现