The automatic type of automatic method does not work. What for?

As a training exercise, I am creating a class to manage the old familiar values โ€‹โ€‹of argc and argv. I save argv as std :: vector for std :: strings. At this point, I would like to iterate over my object, as if it were a vector. The problem I am facing is that my decision is highly dependent on my choice of container, and the compiler crashes when I try to fix it. Note:

So I would like my class to work for this example.

int main(int argc, char* argv) { CLI options(argc, argv); for (auto option : options) { cout << option << endl; } } 

This is pretty trivial, but it took a moment of research. Here is my header file

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

and my source file for the CLI class. (minus includes etc.)

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

This works great, but here is my first problem. If I decide that I want to use a linked list instead of a vector, now I have at least five spots that need to be changed, more if my client code has a dumb day and does not use auto for its loop (or something else, this will happen). It seems like this should be a case of automatic rescue! With the new C ++ functions, I can change the method signature to this:

 ... // Header auto begin(); ... // Source // Possibly without the decltype now? Not sure how or when... auto CLI::begin() -> decltype(arguments.begin()) { return arguments.begin(); } 

This is where I finally get the error message:

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

Good. If I were to guess what that means, I would say that auto in the for loop is looking for a signature for the begin method, hoping to find a specific return type. Instead, he finds auto and panic.

So this theory is correct, and is there a better way to hide the type of container, despite iterators?

PS The more I look at this problem, the more I understand that this functionality is probably not the functionality that I want in the final product anyway. But it still looks like an opportunity to learn something.

+5
source share
1 answer

Since the header does not include code, the compilation unit for main.cpp cannot output the value auto for begin()

This will work better for what you intend:

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

Security note for const: remember that "const_iterator" is a unique type that is not necessarily a constant, and the object that it represents is const. This means that the type is different in that it does not allow you to return a.begin() inside the const function. A naive might try adding the return type const decltype(a.begin()) , but it is still not vector::const_iterator , but rather const vector::iterator .

+2
source

Source: https://habr.com/ru/post/1209777/


All Articles