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小さなコマンドライン環境で処理する必要があるコマンドごとに個別のoptions_descriptionを定義しようとしています。コマンドライン環境を解析するために bison と flex を使用しています。コマンドのすべての引数は、引数の解析のためにこの静的クラスに送信されます。

引数の定義は静的であるため、それらをスタック内のある種のデータ構造にしたくありません (私の考えでは、これは高速でクリーンである可能性があります)。これらのコードは、静的でない場合は問題ないと思いますが、静的な場合はどうなりますか?

4

3 に答える 3

3

toの呼び出し.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

グローバルまたは名前空間スコープでスタンドアロン ステートメントを使用することはできません。

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 に答える
3

options_descriptionから判断すると、2 段階の初期化が必要です。コンストラクターを呼び出してから、コンストラクターを呼び出して設定add_options()します。コードは関数スコープ外で 2 番目のフェーズを実行しようとしましたが、関数スコープ内で呼び出しadd_options()を行う必要があるため失敗しました。

options_descriptionこれを修正する 1 つの方法は、オブジェクトを初期化してデータを入力し、それを返すファクトリ関数を作成することです。この戻りオブジェクトを使用して、静的インスタンスを初期化できます。次に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 に答える