更改 boost::program_options 中的元变量
Change the metavars in boost::program_options
这是一个纯粹的美学问题。
我用 C++ 编写了一个 CLI 程序并使用 boost::program_options
来传递它的参数。
默认情况下,boost 命名所有元变量 arg
。我想改变它。
代码如下:
#include <iostream>
using std::cerr;
using std::cout;
#include <optional>
using std::optional;
#include <string>
using std::string;
#include <boost/program_options.hpp>
using boost::program_options::unknown_option;
#include "Net.h"
#include "GameServer.h"
using proto::GameServer;
namespace args = boost::program_options;
static auto parseArgs(int argc, const char *argv[])
{
args::options_description desc("Command line options");
desc.add_options()
("help,h", "Show this page")
("address,a", args::value<string>()->default_value(net::Defaults::HOST), "IP address to listen on")
("port,p", args::value<unsigned short>()->default_value(net::Defaults::PORT), "Port to listen on")
;
optional<args::variables_map> result;
args::variables_map varMap;
try {
args::store(args::parse_command_line(argc, argv, desc), varMap);
} catch (unknown_option const &error) {
cerr << "Invalid option: " << error.get_option_name() << "\n";
cerr << desc << "\n";
return result;
}
args::notify(varMap);
if (varMap.count("help")) {
cout << desc << "\n";
return result;
}
return result = varMap;
}
int main(int argc, const char *argv[])
{
auto parsedArgs = parseArgs(argc, argv);
if (!parsedArgs.has_value())
return 1;
auto args = parsedArgs.value();
auto address = args.at("address").as<string>();
auto port = args.at("port").as<unsigned short>();
GameServer server(address, port);
server.listen();
}
帮助页面生成的输出:
Command line options:
-h [ --help ] Show this page
-a [ --address ] arg (=127.0.0.1) IP address to listen on
-p [ --port ] arg (=9000) Port to listen on
我想将 -a
的 arg
重命名为 ip_address
,-p
的 portnum
分别重命名。
似乎是 boost::program_options
的未记录部分,我快速查看了 boost::program_options
的实现,发现有一个 global variable 用于控制行为,所以我们提出了一行代码破解:
args::arg = "i_am_not_arg";
修改全局变量不是一个优雅的方式,但我还没有找到任何可用的API来做,你可以多研究并尝试找到更好的解决方案(别忘了在这里通知我! )
将此行插入代码的某个位置,然后我们得到 --help
命令行的输出:
->./a.out --help
Command line options:
-h [ --help ] Show this page
-a [ --address ] i_am_not_arg (=1234) IP address to listen on
-p [ --port ] i_am_not_arg (=42) Port to listen on
关于 SO 提问的建议:
- 提供一个最小的、可复制的程序。您的代码无法在我的机器上编译,因为您使用了未提供的文件中的变量。
@prehistoricpenguin 的回答让我走上了正轨。在 boost 中,typed_value
class 有一个方法 value_name()
来设置参数名称,其工作方式类似于设置默认值,即它修改值对象并 returns 它为后续操作:
static auto parseArgs(int argc, const char *argv[])
{
options_description desc("Command line options");
desc.add_options()
("help,h", "Show this page")
("address,a", value<string>()->default_value(HOST)->value_name("ip_address"),
"IP address to connect to")
("port,p", value<unsigned short>()->default_value(PORT)->value_name("portnum"),
"Port to connect to");
return parseArgDesc(argc, argv, desc);
}
导致:
Command line options:
-h [ --help ] Show this page
-a [ --address ] ip_address (=127.0.0.1)
IP address to connect to
-p [ --port ] portnum (=9000) Port to connect to
这是一个纯粹的美学问题。
我用 C++ 编写了一个 CLI 程序并使用 boost::program_options
来传递它的参数。
默认情况下,boost 命名所有元变量 arg
。我想改变它。
代码如下:
#include <iostream>
using std::cerr;
using std::cout;
#include <optional>
using std::optional;
#include <string>
using std::string;
#include <boost/program_options.hpp>
using boost::program_options::unknown_option;
#include "Net.h"
#include "GameServer.h"
using proto::GameServer;
namespace args = boost::program_options;
static auto parseArgs(int argc, const char *argv[])
{
args::options_description desc("Command line options");
desc.add_options()
("help,h", "Show this page")
("address,a", args::value<string>()->default_value(net::Defaults::HOST), "IP address to listen on")
("port,p", args::value<unsigned short>()->default_value(net::Defaults::PORT), "Port to listen on")
;
optional<args::variables_map> result;
args::variables_map varMap;
try {
args::store(args::parse_command_line(argc, argv, desc), varMap);
} catch (unknown_option const &error) {
cerr << "Invalid option: " << error.get_option_name() << "\n";
cerr << desc << "\n";
return result;
}
args::notify(varMap);
if (varMap.count("help")) {
cout << desc << "\n";
return result;
}
return result = varMap;
}
int main(int argc, const char *argv[])
{
auto parsedArgs = parseArgs(argc, argv);
if (!parsedArgs.has_value())
return 1;
auto args = parsedArgs.value();
auto address = args.at("address").as<string>();
auto port = args.at("port").as<unsigned short>();
GameServer server(address, port);
server.listen();
}
帮助页面生成的输出:
Command line options:
-h [ --help ] Show this page
-a [ --address ] arg (=127.0.0.1) IP address to listen on
-p [ --port ] arg (=9000) Port to listen on
我想将 -a
的 arg
重命名为 ip_address
,-p
的 portnum
分别重命名。
似乎是 boost::program_options
的未记录部分,我快速查看了 boost::program_options
的实现,发现有一个 global variable 用于控制行为,所以我们提出了一行代码破解:
args::arg = "i_am_not_arg";
修改全局变量不是一个优雅的方式,但我还没有找到任何可用的API来做,你可以多研究并尝试找到更好的解决方案(别忘了在这里通知我! )
将此行插入代码的某个位置,然后我们得到 --help
命令行的输出:
->./a.out --help
Command line options:
-h [ --help ] Show this page
-a [ --address ] i_am_not_arg (=1234) IP address to listen on
-p [ --port ] i_am_not_arg (=42) Port to listen on
关于 SO 提问的建议:
- 提供一个最小的、可复制的程序。您的代码无法在我的机器上编译,因为您使用了未提供的文件中的变量。
@prehistoricpenguin 的回答让我走上了正轨。在 boost 中,typed_value
class 有一个方法 value_name()
来设置参数名称,其工作方式类似于设置默认值,即它修改值对象并 returns 它为后续操作:
static auto parseArgs(int argc, const char *argv[])
{
options_description desc("Command line options");
desc.add_options()
("help,h", "Show this page")
("address,a", value<string>()->default_value(HOST)->value_name("ip_address"),
"IP address to connect to")
("port,p", value<unsigned short>()->default_value(PORT)->value_name("portnum"),
"Port to connect to");
return parseArgDesc(argc, argv, desc);
}
导致:
Command line options:
-h [ --help ] Show this page
-a [ --address ] ip_address (=127.0.0.1)
IP address to connect to
-p [ --port ] portnum (=9000) Port to connect to