C++传输参数的技巧

参考高博视觉十四讲的做法

高翔视觉slam14讲资料

调用的顺序

1.将参数传入类型BundleParams中进行构造函数
BundleParams params(argc,argv);
2.构造函数中,会将所有的参数传入到类型CommandArgs中
 BundleParams::BundleParams(int argc, char** argv)
 {  
    arg.param("input", input, "", "file which will be processed");
    arg.param("trust_region_strategy", trust_region_strategy, "levenberg_marquardt",                            
              "Options are: levenberg_marquardt, dogleg.");
    arg.param("linear_solver", linear_solver, "dense_schur",                             // iterative schur and cgnr(pcg) leave behind...
              "Options are: sparse_schur, dense_schur, sparse_normal_cholesky");
    
    arg.param("sparse_linear_algebra_library", sparse_linear_algebra_library, "suite_sparse", "Options are: suite_sparse and cx_sparse.");
    arg.param("dense_linear_algebra_library", dense_linear_algebra_library, "eigen", "Options are: eigen and lapack.");
    
    
    arg.param("ordering",ordering,"automatic","Options are: automatic, user.");
    arg.param("robustify", robustify, false, "Use a robust loss function");
    

    arg.param("num_threads",num_threads,1, "Number of threads.");
    arg.param("num_iterations", num_iterations,10, "Number of iterations.");

    arg.param("rotation_sigma", rotation_sigma, 0.0, "Standard deviation of camera rotation "
              "perturbation.");
    arg.param("translation_sigma", translation_sigma,0.0, "translation perturbation.");
    arg.param("point_sigma",point_sigma,0.0,"Standard deviation of the point "
              "perturbation.");
    arg.param("random_seed", random_seed, 38401,"Random seed used to set the state ");
    arg.param("initial_ply", initial_ply,"initial.ply","Export the BAL file data as a PLY file.");
    arg.param("final_ply", final_ply, "final.ply", "Export the refined BAL file data as a PLY");

    arg.parseArgs(argc, argv);//类型中的参数全部加入到std::vector<CommandArgument> _args中
 }
 3.arg.parseArgs解析这个parser的函数
 3.1 小技巧,解析出-后面的参数
  string name = "-hello";
  string::size_type epos = name.find_first_not_of('-');
  name = name.substr(epos); //hello

 bool CommandArgs::parseArgs(int argc, char** argv, bool exitOnError)
{
  _progName = argv[0]; //去掉第一个参数
  int i;
  for (i = 1; i < argc; i++) {
    string name = argv[i];
    if (name[0] != '-') { // each param has to start with at least one dash
      //cerr << "Error: expecting parameter, got " << name << endl;
      //printHelp(cerr);
      //if (exitOnError)
        //exit(1);
      //return false;
      break;
    }
    /* first check whether it's -- and we should not continue parsing */
    //表示省略
    if (name == "--") {
      ++i;
      break;
    }

    string::size_type dashPos = name.find_first_not_of('-');
    if (dashPos != string::npos)
      name = name.substr(dashPos);

    if (name == "help" || name == "h") {
      printHelp(cout);
      exit(0);
    }
    else {
      // command line argument parsing
      std::vector<CommandArgument>::iterator it = _args.begin();
      for ( ; it != _args.end(); ++it) {
        if (it->name == name) {
          if (it->type == CAT_BOOL) {
            if (!it->parsed) {
              bool* data = static_cast<bool*>(it->data);
              *data = !(*data);
            }
            it->parsed = true;
          } else {
            if(i >= argc-1) {
              cerr << "Argument " << name << "needs value.\n";
              printHelp(cerr);
              if (exitOnError)
                exit(1);
              return false;
            }
            i++;
            str2arg(argv[i], *it);
            it->parsed = true;
          }
          break;
        }
      }
      if (it == _args.end()) {
        cerr << "Error: Unknown Option '" << name << "' (use -help to get list of options).\n";
        if (exitOnError)
          exit(1);
        return false;
      }

    }

  } // for argv[i]

  if ((int)_leftOvers.size() > argc - i) {
    cerr << "Error: program requires parameters" << endl;
    printHelp(cerr);
    if (exitOnError)
      exit(1);
    return false;
  }
  for (size_t j = 0; (i < argc && j < _leftOvers.size()); i++, j++) {
    string* s = static_cast<string*>(_leftOvers[j].data);
    *s = argv[i];
  }

  // the optional leftOvers
  for (size_t j = 0; (i < argc && j < _leftOversOptional.size()); i++, j++) {
    string* s = static_cast<string*>(_leftOversOptional[j].data);
    *s  = argv[i];
  }

  return true;
}

标准的代表输入参数的类

    struct CommandArgument
    {
      std::string name;
      std::string description;
      int type;
      void* data;
      bool parsed;
      bool optional;
      CommandArgument() : name(""), description(""), type(0), data(0), parsed(false), optional(false)
      {}
    };

维护每个参数代表的具体的含义,使用一个枚举类

1,先定义出枚举类,每个值都是代表数字
enum CommandArgumentType
{
  CAT_DOUBLE, 
  CAT_FLOAT, 
  CAT_INT, 
  CAT_STRING, 
  CAT_BOOL, 
  CAT_VECTOR_INT, 
  CAT_VECTOR_DOUBLE
};

2,使用枚举类和字符串关联起来
const char* CommandArgs::type2str(int t) const
{
  switch (t) {
    case CAT_DOUBLE:
      return "<double>";
    case CAT_FLOAT:
      return "<float>";
    case CAT_INT:
      return "<int>";
    case CAT_STRING:
      return "<string>";
    case CAT_BOOL:
      return "<bool>";
    case CAT_VECTOR_INT:
      return "<vector_int>";
    case CAT_VECTOR_DOUBLE:
      return "<vector_double>";
  }
  return "";
}

调用解析的时候的例子

    std::vector<CommandArgument> _args; //第一步把所有的参数给到参数列表中
	void CommandArgs::param(const std::string& name, std::string& p, const std::string& defValue, const std::string& desc)
	{
	  CommandArgument ca;
	  ca.name = name; //参数的名称
	  ca.description = desc; //参数的描述
	  ca.type = CAT_STRING; //参数的类型
	  ca.data = static_cast<void*>(&p); //参数的具体数据,不知道指向什么数据,用一个void指针
	  ca.parsed = false; //还没有解析出来
	  p = defValue; //把内容传给p这个变量
	  _args.push_back(ca);
	}

C++的vector是可以加入空的内容的,例如

keypoint_2_landmark_id.push_back({});
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值