Was mache ich hier ? "std::vector<std::string> myAllArgs(argv, argv + argc);"
-
@manni66 sagte in Was mache ich hier ? "std::vector<std::string> myAllArgs(argv, argv + argc);":
Ja? Ich hatte angenommen, du woltest selber etwas in der Art von vector implementieren.
Irgendwie schon weil ich zumindest jetzt weiß wonach ich jetzt suchen muss. Und der nächste Schritt wäre auch gewesen dass ich die Art von vector implmentieren will. Sonst habe ich immer Probleme das zu verstehen.
also:
MyVector<MyClass> std::vector<MyClass> myElements(elements, elements + 10);
Für ersten Fall brauche ich aber keinen Konstruktor mit string. Das geht auch einfach so.
class MyClass { public: MyClass() { } string sinnlos; }; int main(int argc, char** argv) { MyClass elements[10]; elements[0].sinnlos = "0"; elements[1].sinnlos = "1"; elements[2].sinnlos = "2"; elements[3].sinnlos = "3"; elements[4].sinnlos = "4"; elements[5].sinnlos = "5"; elements[6].sinnlos = "6"; elements[7].sinnlos = "7"; elements[8].sinnlos = "8"; elements[9].sinnlos = "9"; std::vector<MyClass> myElements(elements, elements + 10); for (auto argument : myElements) { cout << argument.sinnlos << endl; } }
hmmmmmmmm dieses/er "Syntax" geht mir schon etwas zu schnell
Aber damit wird es zumindestens klarer.
vector( InputIt first, InputIt last, const Allocator& alloc = Allocator() );
-
Der Sinn deiner Knödelei lässt sich nicht erkennen. Der gleiche Effekt in kurz:
#include <iostream> #include <string> #include <iterator> using namespace std; class MyClass { public: string sinnlos; }; int main(int argc, char** argv) { MyClass elements[] = {"0", "1", "2", "3" }; for (auto& argument : elements) { cout << argument.sinnlos << endl; } }
-
@manni66 sagte in Was mache ich hier ? "std::vector<std::string> myAllArgs(argv, argv + argc);":
Der Sinn deiner Knödelei lässt sich nicht erkennen. Der gleiche Effekt in kurz:
ÄÄ ja natürlich geht das auch kürzer.
Es geht nur um diese Zeile die mir tausend Fragen aufwirft:
std::vector<MyClass> myElements(elements, elements + 10);
Alles anderes ist das drumherum. Der Sinn ist, versuchen zu verstehen was die Zeile genau macht und warum das überhaupt compilierbar ist. Und der Compiler nicht sagt. "Syntax Error myElements is not defined" oder sowas.
-
@manni66 sagte in Was mache ich hier ? "std::vector<std::string> myAllArgs(argv, argv + argc);":
MyClass elements[] = {"0", "1", "2", "3" };
momentmal das ist doch gar nicht kompilierbar das geht doch nur wenn ich MyClass (std::initializer_list<int> list) implementiert habe ...
-
@martin_zi sagte in Was mache ich hier ? "std::vector<std::string> myAllArgs(argv, argv + argc);":
MyClass elements[] = {"0", "1", "2", "3" };
momentmal das ist doch gar nicht kompilierbar das geht doch nur wenn ich MyClass (std::initializer_list<int> list) implementiert habe ...
Hast du das
[]
nachelements
gesehen?
-
@hustbaer sagte in Was mache ich hier ? "std::vector<std::string> myAllArgs(argv, argv + argc);":
@martin_zi sagte in Was mache ich hier ? "std::vector<std::string> myAllArgs(argv, argv + argc);":
MyClass elements[] = {"0", "1", "2", "3" };
momentmal das ist doch gar nicht kompilierbar das geht doch nur wenn ich MyClass (std::initializer_list<int> list) implementiert habe ...
Hast du das
[]
nachelements
gesehen?Ja und mein compiler mag das nicht: "error: conversion from 'const char [2]' to non-scalar type 'MyClass' requested"
class MyClass { public: MyClass() { } sinnlos = myString; }; int main(int argc, char** argv) { MyClass elements[] = {"0", "1", "2", "3" }; return 0; }
Das feature funktioniert doch auch nur wenn die Klasse das implementiert hat.
-
@martin_zi Und wo sagt dir dein Kompiler, dass er hier den std::initializer mag? Er mag einen Konstructor der mit const char[2] irgendwie umgehen kann, z.B. ein Konstruktor, der einen std::string erwartet.
-
@Jockelx sagte in Was mache ich hier ? "std::vector<std::string> myAllArgs(argv, argv + argc);":
@martin_zi Und wo sagt dir dein Kompiler, dass er hier den std::initializer mag? Er mag einen Konstructor der mit const char[2] irgendwie umgehen kann, z.B. ein Konstruktor, der einen std::string erwartet.
Weil mir die Fehlermeldung irgendwie derzeit zu unverständlich ist interpretiere ich einfach irgendwas hinein. Aber du hast recht ich habe da was gemixt. Wenn ich dieses std::initializer_list<int> list habe kanne ich das machen:
MyClass elements3 = {"0", "1", "2", "3" }; //und nicht das: MyClass elements2[] = {"0", "1", "2", "3" };
Der Hinweis mit der [] war mir aber zu wenig und habe ich erst jetzt verstanden was du meinst.
Allerdings muss ich meine Klasse so bauen:
class MyClass { public: MyClass() { } MyClass(const char *mychar) { } }
Sollte das auch funktionieren ?
class MyClass { public: MyClass() { } MyClass(std::string mychar) { } }
Mit std::string gibt es immer noch dieselbe Fehlermeldung.
-
@martin_zi sagte in Was mache ich hier ? "std::vector<std::string> myAllArgs(argv, argv + argc);":
Ja und mein compiler mag das nicht: "error: conversion from 'const char [2]' to non-scalar type 'MyClass' requested"
Du kannst die Elemente einzeln initialisieren:
MyClass elements[] = {{"0"}, {"1"}, {"2"}, {"3"}};
-
Vielleicht etwas Code zum Verständnis wieso, weshalb, warum:
#include <vector> #include <iostream> struct A { A(int i) {} A(int i, int j) {} }; int main() { std::vector<A> a = {{1,2}, 3}; std::cout << a.size(); }
-
@martin_zi
C++ hat die Regel dass immer nur eine "user defined conversion" implizit angewendet wird. D.h. wenn du etwas hast was einFoo
braucht, undFoo
ist mit einemstd::string
erzeugbar, und derstd::string
ist mit einemconst char*
erzeugbar, dann kannst du da nicht einfach "blah" hinschreiben.
Weil dazu zwei "user defined conversions" nötig wären:
1x "eingebaute conversion"const char[5]
->const char*
1x "user defined"const char*
->std::string
1x "user defined"std::string
->Foo
Also Beispiel
void takeFoo(Foo f); void test() { takeFoo("blah"); // geht nicht weil zwei "user defined conversions" nötig takeFoo(std::string{"blah"}); // geht weil nur eine "user defined conversion" nötig takeFoo({"blah"}); // geht auch weil nur eine "user defined conversion" nötig // {"blah"} wird hier als Initialisierung des std::string interpretiert // und danach kommt 1x implizite konvertierung von std::string nach Foo }
Zum Initialisieren eines Arrays brauchst du erstmal die
{}
. Bei einemMyClass
Array müssen die Werte innerhalb der{}
also geeignet seinMyClass
Objekte zu initialisieren. D.h.{"a", "b"}
ist vergleichbar mittakeFoo("blah")
im Beispiel oben, geht also nicht.Bei
{{"a"}, {"b"}}
dagegen werden{"a"}
und{"b"}
als Initialisierung einesstd::string
verstanden, und dann kann mit nur einer "user defined conversion" einMyClass
Objekt gebastelt werden.
-
@martin_zi sagte in Was mache ich hier ? "std::vector<std::string> myAllArgs(argv, argv + argc);":
Ja und mein compiler mag das nicht: "error: conversion from 'const char [2]' to non-scalar type 'MyClass' requested"
Es hat schon seinen Grund, dass in meinem vollständigen Beispiel die Klasse keinen Konstruktor hat.
-
@manni66 Das ist aber wieder ein Spezialfall (alles public Member, keine special member functions etc.). Und mMn. nix was man besonders pushen sollte.
-
@manni66 sagte in Was mache ich hier ? "std::vector<std::string> myAllArgs(argv, argv + argc);":
@martin_zi sagte in Was mache ich hier ? "std::vector<std::string> myAllArgs(argv, argv + argc);":
Ja und mein compiler mag das nicht: "error: conversion from 'const char [2]' to non-scalar type 'MyClass' requested"
Es hat schon seinen Grund, dass in meinem vollständigen Beispiel die Klasse keinen Konstruktor hat.
Äääämmm ahhhhh ja aber genau bei solchen Sachen habe ich ein Verständnis Problem.
Ich erzähle mal so wie ich es verstehe und dann kann man mich korrigieren:Laut Buch und was ich sonst so finde gilt: "Falls kein Konstruktor angegeben wird, wird einer vom System automatisch erzeugt (implizite Konstruktordeklaration)."
Damit hat eine Klasse auch wenn nicht angegebn einen Konstruktor.Will ich wirklich keinen haben muss ich mit delete arbeiten. Also:
class MyClass { MyClass() = delete; };
Weiter steht:
Dieser vordefinierte Konstruktor (englisch default constructor) kann auch selbst
geschrieben werden. Der Standard-konstruktor hat keine Parameter. Für eine Klasse X wird er einfach mit X(); deklariert.Für mich bedeutet das:
class MyClass { public: MyClass() { } sinnlos = myString; };
class MyClass { public: sinnlos = myString; };
Das dass das Gleiche ist. Aber das ist wohl nicht so. Also woher weiß ich was der Compiler wirklich generiert ? Da ist ja dann wohl was da, was ich gar nie geschrieben wurde. Und schreibe ich zuviel ist auf einmal doch was weg
-
@martin_zi sagte in Was mache ich hier ? "std::vector<std::string> myAllArgs(argv, argv + argc);":
Das dass das Gleiche ist. Aber das ist wohl nicht so.
Nein, ist es nicht.
-
@hustbaer sagte in Was mache ich hier ? "std::vector<std::string> myAllArgs(argv, argv + argc);":
@manni66 Das ist aber wieder ein Spezialfall (alles public Member, keine special member functions etc.).
Ja, entsprechend dem sinnlosen Beispiel.
Und mMn. nix was man besonders pushen sollte.
Nein, es ging auch nur um das "bei mir geht ea aber nicht".
-
@martin_zi
Der Konstruktor ist schon fast der selbe, darum geht's aber nicht. Selbst wenn der 100% identisch wäre ginge es nicht.Es geht darum: https://en.cppreference.com/w/cpp/language/aggregate_initialization
-
@manni66 sagte in Was mache ich hier ? "std::vector<std::string> myAllArgs(argv, argv + argc);":
@hustbaer sagte in Was mache ich hier ? "std::vectorstd::string myAllArgs(argv, argv + argc);":
||| @manni66 Das ist aber wieder ein Spezialfall (alles public Member, keine special member functions etc.).
Ja, entsprechend dem sinnlosen Beispiel.
||| Und mMn. nix was man besonders pushen sollte.
Nein, es ging auch nur um das "bei mir geht ea aber nicht".
Der Hinweis hat schon gepasst, vielleicht war es nicht ganz das Thema aber es hat mit was gezeigt was ich nicht ganz bzw. sogar falsch verstanden habe.
@hustbaer
Und danke auch für den Hinweis mit diesem link.Aber zurück zum Anfangs Thema:
Einen Vector erzeuge ich so:
vector<int> vec1;
Oder so:
vector<int> vect(0, 10);
wenn ich nicht den default Konstruktor aufrufen will.
Bzw am Ende so wie in der Anfangsfrage auch so:vector<string> myAllArgs(argv, argv + argc);
Also bräuchte meine Klasse die das können soll in etwa sowas:
template<typename _Tp> class MyVector { public: MyVector() { cout << "ctor MyVector" << endl; } MyVector(_Tp element,int size) { // TODO! } MyVector(_Tp &firstElement, _Tp &lastElement) { _Tp *pf,*pl; pf = &firstElement; pl = &lastElement; while (pf <= pl) { mylist.push_back(*pf); pf++; } } td::list<_Tp> mylist; };
Ok und dann halt noch den Rest der Methoden die ich jetzt aus Faulheit unterschlagen habe...
Also wie Sepp und manni66 schon geschrieben haben einen anderen Vector-Konstruktor aufgerufen. Ist jetzt nicht so elegant aber für mich jetzt etwas verständlicher. Gibts sonst noch wo Logik- oder Denkfehler bei mir ?
-
@martin_zi sagte in Was mache ich hier ? "std::vector<std::string> myAllArgs(argv, argv + argc);":
MyVector(_Tp &firstElement, _Tp &lastElement)
Das ist aber ein merkwürdiger Konstruktor!
Vergleiche mit (4) auf https://en.cppreference.com/w/cpp/container/vector/vector
-
@wob sagte in Was mache ich hier ? "std::vector<std::string> myAllArgs(argv, argv + argc);":
@martin_zi sagte in Was mache ich hier ? "std::vector<std::string> myAllArgs(argv, argv + argc);":
MyVector(_Tp &firstElement, _Tp &lastElement)
Das ist aber ein merkwürdiger Konstruktor!
Vergleiche mit (4) auf https://en.cppreference.com/w/cpp/container/vector/vector
Ja aber besser konnte ich es derzeit nicht lösen bin noch am Anfang....
template< class InputIt > vector( InputIt first, InputIt last, const Allocator& alloc = Allocator() );
Und hier verstehe ich nicht was Allocator sein soll.
std::vector<T,Allocator>::vector
Es ist zwar hier aber ich erzeuge den vector ohne Allocator. Da fählt mir wohl noch wissen mit diesen templates. Genau so subekt ist mir dieses InputIt.