我是 C++ 新手,尝试使用 Boost 的 program_options 标头来创建
vector<string>
位置选项,但无论我做什么,我似乎都无法实际执行任何操作或迭代它们。我目前正在 GCC 14.1.1 上编译为 C++23。
我目前正在使用它作为选项:
po::options_description desc("Testing");
desc.add_options()
("help", "produce help message")
("path,p", po::value< vector<string> >(),
"Path of directory/file");
po::positional_options_description p;
p.add("path", -1);
po::variables_map vm;
po::store(po::command_line_parser(argc, argv).
options(desc).positional(p).run(), vm);
po::notify(vm);
我尝试使用像这样的
for
循环对其进行迭代,我收到 LSP (clangd) 错误,并且我的程序无法编译:
if (vm.count("path")) {
for (auto i : vm.count("path")) {
cout << "Paths are: "
<< i << endl;
}
}
clangd错误:
Invalid range expression of type 'std::map<std::basic_string<char>, boost::program_options::variable_value>::size_type' (aka 'unsigned long'); no viable 'begin' function available
海湾合作委员会错误:
/home/main/projects/cpp-testing/src/new.cpp: In function ‘int main(int, char**)’:
/home/main/projects/cpp-testing/src/new.cpp:26:34: error: ‘begin’ was not declared in this scope
26 | for (auto i : vm.count("path")) {
| ^
/home/main/projects/cpp-testing/src/new.cpp:26:34: note: suggested alternatives:
In file included from /usr/include/c++/14.1.1/string:53,
from /usr/include/c++/14.1.1/bits/locale_classes.h:40,
from /usr/include/c++/14.1.1/bits/ios_base.h:41,
from /usr/include/c++/14.1.1/ios:44,
from /usr/include/c++/14.1.1/ostream:40,
from /usr/include/c++/14.1.1/iostream:41,
from /home/main/projects/cpp-testing/src/new.cpp:1:
/usr/include/c++/14.1.1/bits/range_access.h:114:37: note: ‘std::begin’
114 | template<typename _Tp> const _Tp* begin(const valarray<_Tp>&) noexcept;
| ^~~~~
In file included from /usr/include/c++/14.1.1/string_view:56,
from /usr/include/c++/14.1.1/bits/basic_string.h:47,
from /usr/include/c++/14.1.1/string:54:
/usr/include/c++/14.1.1/bits/ranges_base.h:487:47: note: ‘std::ranges::_Cpo::begin’
487 | inline constexpr ranges::__access::_Begin begin{};
| ^~~~~
In file included from /usr/include/boost/range/functions.hpp:18,
from /usr/include/boost/range/iterator_range_core.hpp:38,
from /usr/include/boost/lexical_cast.hpp:48,
from /usr/include/boost/program_options/value_semantic.hpp:14,
from /usr/include/boost/program_options/options_description.hpp:13,
from /usr/include/boost/program_options.hpp:15,
from /home/main/projects/cpp-testing/src/new.cpp:3:
/usr/include/boost/range/begin.hpp:110:61: note: ‘boost::range_adl_barrier::begin’
110 | inline BOOST_DEDUCED_TYPENAME range_iterator<const T>::type begin( const T& r )
| ^~~~~
In file included from /usr/include/c++/14.1.1/bits/stl_iterator_base_types.h:71,
from /usr/include/c++/14.1.1/bits/stl_construct.h:61,
from /usr/include/c++/14.1.1/bits/char_traits.h:57,
from /usr/include/c++/14.1.1/ios:42:
/usr/include/c++/14.1.1/bits/iterator_concepts.h:983:10: note: ‘std::ranges::__access::begin’
983 | void begin() = delete;
| ^~~~~
/home/main/projects/cpp-testing/src/new.cpp:26:34: error: ‘end’ was not declared in this scope
26 | for (auto i : vm.count("path")) {
| ^
/home/main/projects/cpp-testing/src/new.cpp:26:34: note: suggested alternatives:
/usr/include/c++/14.1.1/bits/range_access.h:116:37: note: ‘std::end’
116 | template<typename _Tp> const _Tp* end(const valarray<_Tp>&) noexcept;
| ^~~
/usr/include/c++/14.1.1/bits/ranges_base.h:488:45: note: ‘std::ranges::_Cpo::end’
488 | inline constexpr ranges::__access::_End end{};
| ^~~
In file included from /usr/include/boost/range/functions.hpp:19:
/usr/include/boost/range/end.hpp:104:61: note: ‘boost::range_adl_barrier::end’
104 | inline BOOST_DEDUCED_TYPENAME range_iterator<const T>::type end( const T& r )
| ^~~
/usr/include/c++/14.1.1/bits/ranges_base.h:138:10: note: ‘std::ranges::__access::end’
138 | void end() = delete;
| ^~~
当我尝试使用参数创建新的
vector<string>
时,我还会收到有关从 std::map<std::basic_string<char>, boost::program_options::variable_value>::size_type
转换的错误。
vector<string> paths = vm.count("path");
clangd错误:
No viable conversion from 'std::map<std::basic_string<char>, boost::program_options::variable_value>::size_type' (aka 'unsigned long') to 'vector<std::string>' (aka 'vector<basic_string<char>>)
海湾合作委员会错误:
/home/main/projects/cpp-testing/src/new.cpp: In function ‘int main(int, char**)’:
/home/main/projects/cpp-testing/src/new.cpp:25:34: error: conversion from ‘std::map<std::__cxx11::basic_string<char>, boost::program_options::variable_value>::size_type’ {aka ‘long unsigned int’} to non-scalar type ‘std::vector<std::__cxx11::basic_string<char> >’ requested
25 | vector<string> paths = vm.count("path");
| ~~~~~~~~^~~~~~~~
此外,我的问题被标记为重复,链接到这个问题。我的问题具体是关于向量的,而链接的问题不是。该线程中给出的答案似乎没有任何明显的方法来使它们适应我想做的事情,除非我在这里遗漏了一些东西(我不会否认这种可能性,考虑到我几乎没有知道我用这种语言做什么)。
你的问题不是太多迭代,而是访问向量。变量映射包含
boost::any
对象。
您可以通过以下方式从地图上获取实际值:
if (vm.count("path")) {
auto& v = vm["path"].as<std::vector<std::string>>();
之后,您可以按照您的尝试进行迭代:
for (auto& s : v)
std::cout << "Path: " << s << std::endl;
#include <boost/program_options.hpp>
#include <iostream>
namespace po = boost::program_options;
int main(int argc, char* argv[]) {
po::options_description desc("Testing");
desc.add_options() //
("help", "produce help message") //
("path,p", po::value<std::vector<std::string>>(), //
"Path of directory/file") //
;
po::positional_options_description p;
p.add("path", -1);
po::variables_map vm;
po::store(po::command_line_parser(argc, argv).options(desc).positional(p).run(), vm);
po::notify(vm);
if (vm.count("help")) {
std::cout << desc << std::endl;
return 1;
}
if (vm.count("path")) {
auto& v = vm["path"].as<std::vector<std::string>>();
for (auto& s : v)
std::cout << "Path: " << s << std::endl;
} else {
std::cout << "Path not set" << std::endl;
}
}
打印:
g++ -std=c++20 -O2 -Wall -pedantic -pthread main.cpp -lboost_{program_options,filesystem}
./a.out -p a -p b --path "c and d"
Path: a
Path: b
Path: c and d