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.