Jwa*_*ton 5 c++ stl auto c++14
作为一个学习练习,我正在构建一个类来管理旧的熟悉的argc和argv值为main.我将argv存储为std :: strings的std :: vector.目前我想循环我的对象,好像它是向量.我遇到的问题是我的解决方案高度依赖于我对容器的选择,当我尝试修复它时编译器会中断.注意:
这是我希望我的班级为这个例子工作的方式.
int main(int argc, char* argv) {
CLI options(argc, argv);
for (auto option : options) {
cout << option << endl;
}
}
Run Code Online (Sandbox Code Playgroud)
这是相当微不足道的,但确实需要一点时间的研究.这是我的头文件
typedef char* cstring;
class CLI {
std::vector<std::string> arguments;
public:
CLI(const int argc, const cstring argv[]);
std::vector<std::string>::const_iterator begin();
std::vector<std::string>::const_iterator end();
};
Run Code Online (Sandbox Code Playgroud)
和我的CLI类的源文件.(减去包括等)
CLI::CLI(const int argc, const cstring argv[]) {
arguments = std::vector<std::string>(argv, argv + argc);
}
std::vector<std::string>::const_iterator CLI::begin() {
return arguments.begin();
}
std::vector<std::string>::const_iterator CLI::end() {
return arguments.end();
}
Run Code Online (Sandbox Code Playgroud)
这很好用,但这是我的第一个问题.如果我决定使用链接列表而不是向量,我现在至少有五个需要更改的位置,如果我的客户端代码有一个愚蠢的日子并且不使用auto进行循环(或者其他否则它确实).这感觉应该是一个自动救援的案例!使用新的C++功能,我应该能够将方法签名更改为:
... // Header
auto begin();
... // Source
// Possibly without the decltype now? Not sure how or when...
auto CLI::begin() -> decltype(arguments.begin()) {
return arguments.begin();
}
Run Code Online (Sandbox Code Playgroud)
这是我最终得到错误的地方:
.../main.cpp: In function ‘int main(int, char**)’:
.../main.cpp:10:22: error: use of ‘auto CLI::begin()’ before deduction of ‘auto’
for (auto option : options) {
^
.../main.cpp:10:22: error: invalid use of ‘auto’
Run Code Online (Sandbox Code Playgroud)
好的.如果我不得不猜测这意味着什么,我会说for循环中的auto正在查找begin方法的签名,希望找到具体的返回类型.它发现的是汽车和恐慌.
那么,这个理论是否正确,是否有更好的方法来隐藏容器类型,尽管迭代器?
PS我越看这个问题,我越发现这个功能可能不是我想要的最终产品功能.但这仍然是一个学习东西的机会.
auto
由于头文件不包含代码,因此main.cpp的编译单元无法推导出for的含义begin()
这会更好地实现您的意图:
头文件.h
#include <vector>
class A {
public:
std::vector<int> a;
decltype(a.begin()) begin();
decltype(a.cbegin()) cbegin() const;
};
Run Code Online (Sandbox Code Playgroud)
头文件.cpp
#include "header.h"
decltype(A::a.begin()) A::begin() {
return a.begin();
}
decltype(A::a.cbegin()) A::cbegin() const {
return a.cbegin();
}
Run Code Online (Sandbox Code Playgroud)
主程序
#include "header.h"
int main(int argc, char **argv) {
A a;
auto b = a.begin();
auto cb = a.cbegin();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
关于 const 安全性的说明:请记住,“const_iterator”是一种独特的类型,它本身不一定是 const,但它表示的对象是 const。这意味着类型不同,这会阻止您a.begin()
在 const 函数内部返回。天真的人可能会尝试添加const decltype(a.begin())
返回类型,但这仍然不是 avector::const_iterator
而是const vector::iterator
.