Jako ćwiczenie edukacyjne buduję klasę do zarządzania starymi znanymi wartościami argc i argv do main. Przechowywuję argv jako std :: vector std :: string. Na razie chciałbym zapętlić się nad moim obiektem, jak gdyby był to wektor. Problem, który mam, polega na tym, że moje rozwiązanie staje się wysoce zależne od mojego wyboru kontenera i kompilator ulega przerwaniu, gdy próbuję go naprawić. Obserwuj:Automatyczny typ do metody automatycznej kończy się niepowodzeniem. Czemu?
W ten sposób chciałbym, aby moja klasa pracowała dla tego przykładu.
int main(int argc, char* argv) {
CLI options(argc, argv);
for (auto option : options) {
cout << option << endl;
}
}
Jest to dość trywialne, ale wymagało to momentu badań. Oto mój plik nagłówkowy
i mój plik źródłowy dla klasy CLI. (minus zawiera itd.)
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();
}
To działa pięknie, ale tutaj jest mój pierwszy problem. Jeśli zdecyduję, że chcę użyć połączonej listy zamiast wektora, mam teraz co najmniej pięć punktów, które muszą się zmienić, więcej, jeśli mój kod klienta ma głupi dzień i nie używa automatycznie dla swojej pętli (lub cokolwiek innego inaczej to robi). Wydaje się, że powinno to być auto-to-the-rescue! Dzięki nowym funkcjom C++ powinien być w stanie zmienić podpis metody to:
... // Header
auto begin();
... // Source
// Possibly without the decltype now? Not sure how or when...
auto CLI::begin() -> decltype(arguments.begin()) {
return arguments.begin();
}
To gdzie w końcu pojawia się błąd:
.../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’
porządku. Gdybym miał zgadywać, co to oznacza, powiedziałbym, że auto w pętli for szuka podpisu dla metody początku, mając nadzieję znaleźć konkretny typ zwrotu. Zamiast tego znajdzie się auto i panika.
Czy ta teoria jest poprawna i czy istnieje lepszy sposób na ukrycie kontenera pomimo iteratorów?
P.S. Im więcej patrzę na ten problem, tym bardziej zdaję sobie sprawę, że ta funkcja prawdopodobnie nie jest funkcją, jaką chcę w końcowym produkcie. Ale wciąż wydaje się, że można się czegoś nauczyć.
Dlaczego nie po prostu opcje 'std :: vector (int argc, const char * const * argv) {return {argv, argv + argc}; } '? –
Casey
Ponieważ w przyszłości chciałbym móc korzystać z tej klasy, aby analizować opcje wewnętrznie. W ten sposób mogłem zastosować metody 'bool' dla każdej opcji zamiast szukać ich na zewnątrz. – Jwashton