自动类型到自动方法失败。为什么?

时间:2014-12-23 15:13:07

标签: 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;
  }
}

这是相当微不足道的,但确实需要一点时间的研究。这是我的头文件

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();
};

和我的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();
}

这很好用,但这是我的第一个问题。如果我决定使用链接列表而不是向量,我现在至少有五个需要更改的位置,如果我的客户端代码有一个愚蠢的日子并且不使用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();
}

这是我最终收到错误的地方:

.../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’

好。如果我不得不猜测这意味着什么,我会说for循环中的auto正在查找begin方法的签名,希望找到具体的返回类型。它发现的是汽车和恐慌。

那么,这个理论是否正确,是否有更好的方法来隐藏容器类型,尽管有迭代器?

P.S。我越看这个问题,我越发现这个功能可能不是我想要的最终产品功能。但这仍然是学习一些东西的机会。

1 个答案:

答案 0 :(得分:2)

由于标题不包含代码,因此main.cpp的编译单元无法推断出auto

begin()的含义

这样可以更好地满足您的需求:

<强> Header.h

#include <vector>                                                                  

class A {
public:
        std::vector<int> a;
        decltype(a.begin()) begin();
        decltype(a.cbegin()) cbegin() const;
};

<强> Header.cpp

#include "header.h"
decltype(A::a.begin()) A::begin() {
        return a.begin();
}
decltype(A::a.cbegin()) A::cbegin() const {
        return a.cbegin();
}

<强>的main.cpp

#include "header.h"
int main(int argc, char **argv) {
        A a;
        auto b = a.begin();
        auto cb = a.cbegin();
        return 0;                                                               
}

关于const安全性的注释:记住“const_iterator”是一个唯一的类型,它不一定是const本身,而是它所代表的对象是const。这意味着类型不同会阻止您在const函数内返回a.begin()。天真可能会尝试添加const decltype(a.begin())返回类型,但仍然不是vector::const_iterator而是const vector::iterator