0

基本上是下面的代码,不能通过编译器(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

任何的想法?

PS我正在尝试为我需要在小型命令行环境中处理的每个命令定义一个单独的选项描述。我正在使用 bison 和 flex 来解析命令行环境。命令的所有参数都将发送到这个静态类进行参数解析。

由于参数定义是静态的,我不想让它们成为堆栈中的某种数据结构(只是在我看来这可能是快速和干净的)。我认为如果它们不是静态的,这些代码会没问题,但如果它们是静态的会发生什么?

4

3 回答 3

3

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

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

int main () {
  PopulateOptions();
}
于 2012-05-14T17:40:33.410 回答
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);
于 2012-05-14T17:44:45.673 回答
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, 来代替。

于 2012-05-14T18:35:17.983 回答