使用boost :: program_options作为类的静态成员

时间:2012-05-14 17:28:41

标签: c++ boost static-members boost-program-options

基本上它是以下代码,它不能通过编译器(g ++)

#include <boost/program_options.hpp>
#include <iostream>
using std::cout;
using std::endl;
namespace po = boost::program_options;

class static_class {
public:
  static po::options_description cmd_opt;    // here is the definition
};

po::options_description static_class::cmd_opt("dummy");
// the line below cannot pass the compiler !!!
static_class::cmd_opt.add_options()
("help", "show usage info.")
;

main() {
  cout << static_class::cmd_opt << endl;
}

错误消息:

test.cpp:16:1: error: ‘cmd_opt’ in class ‘static_class’ does not name a type

有什么想法吗?

P.S。 我正在尝试为我需要在小命令行环境中处理的每个命令定义一个单独的options_description。我正在使用bison和flex来解析命令行环境。命令的所有参数都将被发送到此静态类以进行参数解析。

由于参数定义是静态的,我不想在堆栈中使它们成为某种数据结构(在我看来,这可能是快速而干净的)。我认为如果这些代码不是静态的,那么这些代码就可以了,但是如果它们发生了什么呢

3 个答案:

答案 0 :(得分:3)

.add_options()的调用是函数调用,而不是声明。您正在尝试在函数外部运行代码。试试这个:

// untested
void PopulateOptions() {
  static_class::cmd_opt.add_options()
    ("help", "show usage info.")
    ;
}

int main () {
  PopulateOptions();
}

答案 1 :(得分:3)

options_description判断它需要两阶段初始化:调用构造函数然后调用add_options()来填充它。您的代码尝试在函数范围之外执行第二阶段并因为调用add_options()必须在函数范围内完成而失败。

解决此问题的一种方法是创建一个工厂函数,初始化并填充options_description对象并将其返回。此返回对象可用于初始化静态实例static_class::cmd_opt,例如:

// in .cc

namespace {

po::options_description make_options_description() {
    po::options_description opt("dummy");
    opt.add_options() // ... populate ...
    return opt;
}

}

po::options_description static_class::cmd_opt = make_options_description();

另一个选项是公开一个填充引用传递的po::options_description对象的函数,而不是暴露po::options_description静态成员,例如:

class static_class {
public:
    // requires only a forward declaration of po::options_description
    static void add_options(po::options_description&);
};

// in .cc
void static_class::add_options(po::options_description& opt) {
    opt.add_options() // ... populate ...
}

然后在main()

中的某个地方
po::options_description opt;
static_class::add_options(opt);
another_static_class::add_options(opt);
yet_another_static_class::add_options(opt);

答案 2 :(得分:3)

不允许在全局或命名空间范围内拥有独立语句。

您可以通过使用扩展add_options表达式的返回值来声明和初始化虚拟变量来解决此问题,如下所示。

po::options_description static_class::cmd_opt("dummy");

auto const dummy = cmd_opt.add_options()
  ("help", "show usage info.")
  ;

如果您的C ++版本不支持auto,那么您可以使用该类型的全名po::options_description_easy_init