C++ Boost程序选项在变量映射上迭代

C++ Boost程序选项在变量映射上迭代,c++,boost,c++11,boost-program-options,C++,Boost,C++11,Boost Program Options,这里的要点是vm包含相同类型的键,但值的类型不同,在本例中,我将uint32\u t与std::string混合使用 如何迭代这种容器?我希望避免使用冗长的方法,所以我尝试迭代这个数据结构 编辑: 我忘了写下来,但很明显 for (const auto& it : vm) { std::cout << it.first.c_str() << " " << it.second.as<it.pair::se

这里的要点是
vm
包含相同类型的
,但值的类型不同,在本例中,我将
uint32\u t
std::string
混合使用

如何迭代这种容器?我希望避免使用冗长的方法,所以我尝试迭代这个数据结构

编辑:

我忘了写下来,但很明显

for (const auto& it : vm) {
      std::cout << it.first.c_str() << " "
                << it.second.as<it.pair::second_type>() << "\n";
    }

我没有专门研究boost::program_options模板,但您可能会做一些一般性的事情,比如使用模板函数,根据类型对命令进行不同的解析:

namespace po = boost::program_options;
模板
无效HandleCommand(T命令)
{
//通解
}
模板
void HandleCommand(const-po::value和command)
{
//用绳子做点什么
}
模板
void HandleCommand(const-po::value和command)
{
//对无符号int进行处理
}

boost::program\u options::variable\u map
本质上是一个
std::map
,这意味着它使用类型擦除来存储值。因为原始类型丢失了,所以如果不将其转换为正确的类型,就无法提取它。您可以实现第二个
映射
,该映射包含选项名称作为键,提取函数作为值,允许您在运行时将值分派给相应的提取器

template <typename T>
void HandleCommand( T command )
{
    // Generic solution
}

template <>
void HandleCommand( const po::value<std::string>& command )
{
    // Do something with the string
}

template <>
void HandleCommand( const po::value<uint32_t>& command )
{
    // Do something with the unsigned int
}
然后您的循环将如下所示:

auto extract_uint32_t = [](boost::variable_value const& v) {
                             std::cout << v.as<std::uint32_t>();
                        };
for(const auto&it:vm){

std::coutboost
variable\u map
使用
boost::any
作为值,以便您可以尝试使用
boost::any\u cast
查找类型。 也许是这样的

for (const auto& it : vm) {
  std::cout << it.first.c_str() << " "
  extractor_obj[it.first](it.second) 
  std::cout << "\n";
}
for(const auto&it:vm){

std::cout我认为比迭代参数更好的方法是使用

示例用法:

for (const auto& it : vm) {
  std::cout << it.first.c_str() << " ";
  auto& value = it.second.value();
  if (auto v = boost::any_cast<uint32_t>(&value))
    std::cout << *v;
  else if (auto v = boost::any_cast<std::string>(&value))
    std::cout << *v;
  else
    std::cout << "error";
}
po::位置选项描述p;
说明添加选项()
(...);
p、 添加(“opt1”,1);
p、 添加(“opt2”,1);
p、 添加(“opt3”,1);
如果(vm.size()!=3)
{
标准:cerr
auto extract_uint32_t = [](boost::variable_value const& v) {
                             std::cout << v.as<std::uint32_t>();
                        };
for (const auto& it : vm) {
  std::cout << it.first.c_str() << " "
  extractor_obj[it.first](it.second) 
  std::cout << "\n";
}
for (const auto& it : vm) {
  std::cout << it.first.c_str() << " ";
  auto& value = it.second.value();
  if (auto v = boost::any_cast<uint32_t>(&value))
    std::cout << *v;
  else if (auto v = boost::any_cast<std::string>(&value))
    std::cout << *v;
  else
    std::cout << "error";
}
po::positional_options_description p;
desc.add_options()
(...);
p.add("opt1", 1);
p.add("opt2", 1);
p.add("opt3", 1);

if (vm.size() != 3)
{
    std::cerr << "Command must be have 3 parameters.\n";
    return 1;
}