c++ - Boost 程序选项和 shared_ptr

标签 c++ boost shared-ptr boost-program-options

我正在尝试使用一个类来为不同的应用程序动态组合程序选项。当对 desc 使用普通指针时,一切正常。在以下使用 shared_ptr 的情况下,解析器无法识别添加的程序选项。

我错过了什么?

非常感谢。

namespace config = boost::program_options;

class Parser {

public:

  Parser();

  void add_all();
  void add_x_options();
  void add_y_options();
  void add_z_options();

  void parse(int argc, char** argv);

  std::shared_ptr<boost::program_options::options_description> desc;

};


Parser::Parser() {
  desc = std::shared_ptr<boost::program_options::options_description>(new boost::program_options::options_description("Options"));
}


void Parser::add_x_options() {
  ...
  desc->add_options()
    ("option1", config::value<std::string>()->required())
    ("option2", config::value<std::string>()->required());
}

void Parser::parse(int argc, char** argv) {
  config::variables_map vmap;

  try {
    config::store(config::parse_command_line(argc, argv, *desc), vmap);

    if (vmap.count("help")) {
      std::cout << *desc << std::endl;
      return false;
    }

    vmap.notify();
  }
  catch(std::exception& e) {
    std::cout << "Error message.\n";
    return false;
  }
  return true;
}

最佳答案

我不知道你错过了什么,但它可能不在显示的代码中。除非你真的忘记及时调用 add_x_options()

这是我的测试程序:看 Live On Coliru

int main()
{
    do_test({ "--help" });
    do_test({ "--option1" });
    do_test({ "--option1", "value1" });
    do_test({ "--option2", "value2" });
    do_test({ "--option1", "value1", "--option2", "value2" });
}

哪些输出(我在 add_x_options 中添加了 --help 选项以便对其进行测试):

---------------------------------------------------------------------------
Test: fake_program.exe --help 
without add_x_options: Error message: unrecognised option '--help'
after add_x_options: Options:
  --help                print usage instructions
  --option1 arg
  --option2 arg

---------------------------------------------------------------------------
Test: fake_program.exe --option1 
without add_x_options: Error message: unrecognised option '--option1'
after add_x_options: Error message: the required argument for option '--option1' is missing
---------------------------------------------------------------------------
Test: fake_program.exe --option1 value1 
without add_x_options: Error message: unrecognised option '--option1'
after add_x_options: Error message: the option '--option2' is required but missing
---------------------------------------------------------------------------
Test: fake_program.exe --option2 value2 
without add_x_options: Error message: unrecognised option '--option2'
after add_x_options: Error message: the option '--option1' is required but missing
---------------------------------------------------------------------------
Test: fake_program.exe --option1 value1 --option2 value2 
without add_x_options: Error message: unrecognised option '--option1'
after add_x_options: 

完整代码

#include <boost/program_options.hpp>
#include <boost/config.hpp>
#include <memory>
#include <iostream>

class Parser {
    public:
        Parser();
        void add_all();
        void add_x_options();
        void add_y_options();
        void add_z_options();
        bool parse(int argc, char** argv);
    private:
        std::shared_ptr<boost::program_options::options_description> desc;
};


Parser::Parser() {
    desc = std::shared_ptr<boost::program_options::options_description>(new boost::program_options::options_description("Options"));
}

namespace config = boost::program_options;

void Parser::add_x_options() {
    //...
    desc->add_options()
        ("help",    "print usage instructions")
        ("option1", config::value<std::string>()->required())
        ("option2", config::value<std::string>()->required());
}

bool Parser::parse(int argc, char** argv) {
    config::variables_map vmap;

    try {
        config::store(config::parse_command_line(argc, argv, *desc), vmap);

        if (vmap.count("help")) {
            std::cout << *desc << std::endl;
            return false;
        }

        vmap.notify();
        return true;
    }
    catch(std::exception& e) {
        std::cout << "Error message: " << e.what() << "\n";
        return false;
    }
}

void do_test(std::initializer_list<const char*> args)
{
    std::string fake_program = "fake_program.exe";
    std::vector<char*> fake_argv { &fake_program[0] };
    for(auto&& arg : args)
        fake_argv.push_back(const_cast<char*>(arg));

    Parser parser;

    std::cout << "---------------------------------------------------------------------------\n";
    std::cout << "Test: ";
    for(auto const& a : fake_argv)
        std::cout << a << " ";
    std::cout << "\n";

    std::cout << "without add_x_options: ";
    parser.parse(fake_argv.size(), fake_argv.data());

    std::cout << "after add_x_options: ";
    parser.add_x_options();
    parser.parse(fake_argv.size(), fake_argv.data());
}

int main()
{
    do_test({ "--help" });
    do_test({ "--option1" });
    do_test({ "--option1", "value1" });
    do_test({ "--option2", "value2" });
    do_test({ "--option1", "value1", "--option2", "value2" });
}

关于c++ - Boost 程序选项和 shared_ptr,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22469422/

相关文章:

c++ - boost asio ssl - 尝试在连接成功后发送请求

c++ - 指针是否允许在单继承中更改值?

c++ - 不同编译器的 DLL 兼容性

c++ - 获得更好的 iostream 错误消息

c++ - 将 make_unique<X> 分配给 shared_ptr<X>

c++ - 在设计良好的代码中,您是否应该期望 weak_ptr 的锁定总是成功?

c++ - 为什么 boost shared_ptr 原子操作会导致 SIGSEGV

constexpr 和返回模板函数的 C++0x 错误

c++ - 在 C++ 中放置新的 VS 显式构造函数调用

c++ - Boost 1.56 with QT creator, "LNK1104: cannot open file ' libboost_unit_test_framework-vc100-mt-gd-1_56.lib'”