View Full Version : C++ error for vector<string>
Fanowene
10-26-2008, 11:09 PM
I'm trying to write this program in C++ for my Computer Science lab and I just keep getting a compile time error I can't figure out. I copied the code that was giving me problems into a separate file to make sure that was the only issue and I'm still getting the error.
#include <vector>
using std::vector;
#include <string>
using std::string;
int main() {
string rhs = "bla";
vector<string> v(rhs);
return 0;
}
Gives me a compiler error on the line for "vector<string> v(rhs);" saying "no matching function for call to 'std::vector(std::string, strd::allocator<std::string> >::vector(std::string&)' " (and so on for about 10 lines).
If I replace that line with two lines of code, using push_back, then I get an even longer and uglier error message, maybe even more than 100 lines (Cygwin won't even display the first part of the error message anymore because the error message has too many lines).
Does anybody here know what could be going wrong? I'm compiling using a gcc compiler for Cygwin. I have very little experience with C++.
Josephine1012
10-26-2008, 11:40 PM
string rhs = "bla";
vector <string> v;
v.push_back(rhs);
Is that what's giving you that long compiler error?
I haven't touched C++ in over 3 years, so I might not be much help. The above is the first thing that comes to mind...
If that doesn't work it might be your include statements. It seems that it's missing a handle to some lib, but I'm not sure which one, I bet Monte might have a better idea.
Fanowene
10-26-2008, 11:42 PM
string rhs = "bla";
vector <string> v;
v.push_back(rhs);
Is that what's giving you that long compiler error?
Yes, exactly.
I've been googling this for quite a while and nobody seems to be doing it any different... Or maybe I'm just overlooking something.
HackerX
10-27-2008, 01:37 AM
This
// VectorTest.cpp : main project file.
#include "stdafx.h"
#include <vector>
#include <string>
using namespace System;
int main(array<System::String ^> ^args)
{
std::string rhs = "blah";
std::vector<std::string> v;
v.push_back(rhs);
return 0;
}
works fine for me
or...
// VectorTest.cpp : main project file.
#include "stdafx.h"
#include <vector>
#include <string>
using std::string;
using std::vector;
using namespace System;
int main(array<System::String ^> ^args)
{
string rhs = "blah";
vector<string> v;
v.push_back(rhs);
return 0;
}
Fanowene
10-27-2008, 02:25 AM
works fine for me
Meaning that my code should be ok? You're using some Microsoft software, right (because of the '#include "stdafx.h"', according to To view links or images in this forum your post count must be 2 or greater. You currently have 0 posts.).
I'm using a GCC compiler. According to Wikipedia there's a difference?
I should make sure my code works with GCC since that's what my prof is using...
Thanks for all the responses so far! Looks like this project will require an all-nighter...
Edit: Well, actually g++, not gcc. But apparently that doesn't make a difference when it comes to error messages... (at the moment).
Fanowene added to this post, 19 minutes and 17 seconds later...
I'm having a similar error with an iterator now, having to do with an output stream (trying to overload the << operator).
void Grammar::print( std::ostream& os ) const {
map<string, vector<string> >::iterator map_iter;
for(map_iter = rules.begin(); map_iter != rules.end(); map_iter++) {
os << "{\n" << map_iter->first << ">\n";
}
}
gives me a "no match for 'operator=' in map_iter" error (also 10+ lines for that error message). For some reason the compiler doesn't have a problem with me doing the same thing iterating through the vector, though (just using
os << *vec_iter << ";\n";
and some other minor modifications I couldn't apply for the actual map iteration. However, it is possible that the compiler doesn't have a problem with it because the for loop for the vector is nested in the for loop for the map.
I wonder what is going on?
Fanowene added to this post, 19 minutes and 47 seconds later...
Back to the vectors:
If I just use ints instead of strings, then it works... But of course I want to use strings, not ints... But it's good to know that it works with ints.
melon
10-27-2008, 03:02 AM
Using g++, the following code (similar to HackerX's and Josephine1012's) should work:
#include <iostream>
#include <string>
#include <vector>
int main()
{
using namespace std;
vector<string> v;
string s = "zero";
v.push_back(s);
v.push_back("one");
cout << "The first element of v is " << v[0] << endl;
cout << "The second element of v is " << v[1] << endl;
return 0;
}
I'm not sure why (so this post may not help you much) or the exact details, but initializing a vector to an STL object is problematic; I have run into the same issue when attempting to create a vector of STL maps (and, additionally, with some of my own custom classes). Rather than assigning upon initialization, use the push_back() method instead. I vaguely remember this having something to do with either copy constructors or assignment operators in classes, but I'm not entirely sure; I would actually be interested to know the reasoning for this, if anyone could explain.
Fanowene
10-27-2008, 05:04 AM
Thanks, melon. It's working now. But I thought I tried that one out before and it didn't work? Weird. I'm just glad it's working now (except for some issues I'm having with cout, apparently...).
I think the problems I'm having now might have to do with the overloading of the << operator? But the prof required that we do the overloading, so I can't just get rid of that.
Is there a way to force the program to use the std:<< ?
Fanowene added to this post, 62 minutes and 42 seconds later...
Could somebody tell me the best way to overload the << operator? I think what I need is a way to restrict it to a class called "Grammar". "Grammar" is included in "RandomSentenceGenerator", which has a private instance of Grammar, and also uses cout, but shouldn't use the << operator defined in "Grammar" unless what it is printing actually is a Grammar.
So far I haven't been able to restrict it... I'm still looking for more info online.
Fanowene added to this post, 7 minutes and 24 seconds later...
But that other elements that aren't Grammars are printed out as if they were Grammars shouldn't actually happen in the first place, right? This is so confusing...
Fanowene added to this post, 38 minutes and 8 seconds later...
Ok, I've managed to narrow the error down quite a bit. I don't think it has to do with overloading at all. Just a stupid assigning a constant to a non-constant thing... and the compiler only told me this because I rearranged some of the code.
HackerX
10-27-2008, 02:04 PM
Meaning that my code should be ok? You're using some Microsoft software, right (because of the '#include "stdafx.h"', according to To view links or images in this forum your post count must be 2 or greater. You currently have 0 posts.).
I'm using a GCC compiler. According to Wikipedia there's a difference?
For completeness's sake, yeah, I just started an empty C++ project in visual studio (first time i've opened it in about a year). The extra header etc won't make a difference. Twas just the quickest way for me to experiment.
Fanowene
10-27-2008, 03:26 PM
In the end I didn't have enough time to finish the lab before class. So that's pretty frustrating. But oh well, life goes on. I'm doing well enough in that class at the moment anyway. I just hope I don't loose too many points on the lab. And this means I really have to study for the midterm were having for that class on Wednesday. I don't want to count on just being able to figure things out as I go along on this one now that the lab didn't go too well.
Thanks for all of your help! :-)
DoubleReedKurt
10-27-2008, 09:20 PM
Hi, I just spent the last year learning C++ in graphic, gory detail for work. (Working with a bunch of Win32 APIs and device drivers, basically a C/C++ shop so I have to use it every day.)
htt p://ww w.cplusplus.com/reference/
This website will be your best friend. Always have it open while you are coding. Refer to the API documentation for whatever you are working with (vector, string, cout, whatever).
There is also the standard C++ bible: "The C++ Programming Language" by Bjarne Stroustrup.
[rant mode]
The STL basically just sucks. The whole template thing is basically a way to try and get #defines from C "right". Anyone who disagrees on this: take a look at the trainwreck that is vector<bool>.
Another thing: what "genius" came up with the C++ standard out?
cout << "Random syntax like this is what makes C++ hard to use."
<< "\n I mean, it sort of makes sense if you squint at it"
<< "\n 'Left Shifting' into the stream.... but not really.";
I could go on: initializer lists. The no operator constructor.
myObject foo(1); //declares new var of type "myObject" and constructs it with an integer parameter of "1"
myObject foo2(); //declares a new FUNCTION named foo2 that return type of "myObject"
The entire language is just a huge pile of "gotchas". This needlessly confusing and non-intuitive syntax is great if you want to show off all the clever tricks you can think up to use the language constructs in new ways. If you want to actually get work done, they are useless.
You know the C++ standard scrupulously avoids mentioning the word "file"? It calls them "compilation units". This is intentional in case there are aliens on Mars or something that want to use C++ but don't store their code in a file system.
The saving grace of C++ is that it has a decent, workable sub-language built in: C.
To read a discussion of the problems C++ has which no other mainstream language has, go here:
htt p:/ /yosefk.com/c++fqa/defective.html
[/rant mode]
Sorry to hear that you are stuck in the class and don't really have a choice in what language you want to use. I guess for this lab it is too late. However, if you run into trouble in the future, feel free to drop me an email and I might be able to help. (No promises that I'll be around in time, but worth a try.)
(Oh yea, the problem you were having is that vector<T> does not define a constructor which takes a parameter of T. What you want to do is this:
vector<string> blah(myString, 1)
This will call the constructor which takes 2 parameters: (T, size_t)... size_t is fancy C++ speak for int.
Another option is to use the constructor which takes two pointers as parameters:
vector<string> blah(&myString, &myString+1)
This says "start loading strings from the location of myString in memory. stop at the location one after the location of myString in memory")
DoubleReedKurt added to this post, 30 minutes and 8 seconds later...
I think what the prof wants you to do is overload the ostream operator for your type of Grammar.
Here is what the C++ FAQ (an excellent resource) has to say on the topic:
ww w.parashift.com/c++-faq-lite/input-output.html#faq-15.8
Basically, ostream does some fancy template business that lets you define it for new types. Make a friend function inside your class...
class Grammar
{
//blah blah...
friend ostream& operator<<(ostream&out, const Grammar& gram);
}
ostream& operator<<(ostream& out, const Grammar& gram)
{
out << "(" << gram.name()/*or whatever you want to output*/ << ")";
return out;
}
This is basically an exercise in mental masturbation. It is hard to even theoretically conceive of a situation where this syntax would be superior to just defining a function inside Grammar to print:
class Grammar
{
public:
void printYoSelf(ostream& out);
};
Plus, this would have the added benefit of letting you use the return type for something useful like an error code if you wanted to, instead of the "clever" ostream chaining. Or better yet, screw the C++ ostream business and just use a C FILE* parameter.
cout << "Grammar:" << myGrammar <<endl;
VERSUS
cout << "Grammar:";
myGrammar.printYoSelf(cout);
Of course if you did that, you wouldn't get to enjoy having 30 lines of mangled template garbage every time you have a compile or debug error.
Fanowene
10-27-2008, 09:26 PM
Thanks. :-)
HackerX
10-27-2008, 09:55 PM
(Oh yea, the problem you were having is that vector<T> does not define a constructor which takes a parameter of T. What you want to do is this:
vector<string> blah(myString, 1)
This will call the constructor which takes 2 parameters: (T, size_t)... size_t is fancy C++ speak for int.
Another option is to use the constructor which takes two pointers as parameters:
vector<string> blah(&myString, &myString+1)
This says "start loading strings from the location of myString in memory. stop at the location one after the location of myString in memory")
Except, if the constructor is expecting a size_t, then it's probably expecting the actual size of the object. i.e:
vector<string> blah(myString, sizeof(myString));
Doing that with an object rather than a primitive type (for T) seems... scary to me. If it even works.
Otherwise, I tend to agree with you about C++'s con's.
DoubleReedKurt
10-27-2008, 10:01 PM
Hi HackerX,
I screwed up the signature a little bit. I got the order mixed up, and the integer is called "size_type".
"explicit vector ( size_type n, const T& value= T(), const Allocator& = Allocator() );
Repetitive sequence constructor: Initializes the vector with its content set to a repetition, n times, of copies of value."
HackerX
10-27-2008, 11:16 PM
Hi HackerX,
I screwed up the signature a little bit. I got the order mixed up, and the integer is called "size_type".
"explicit vector ( size_type n, const T& value= T(), const Allocator& = Allocator() );
Repetitive sequence constructor: Initializes the vector with its content set to a repetition, n times, of copies of value."
Yeah, I think though that this:
const Allocator& = Allocator()
Doesn't translate nicely to something you can pull from std::string, hence the errors.
DoubleReedKurt
10-28-2008, 07:00 PM
Yeah, I think though that this:
const Allocator& = Allocator()
Doesn't translate nicely to something you can pull from std::string, hence the errors.
Yea, allocators only exist to make STL error messages uglier. :-p
The idea was that at some undefined point in the future, everyone would start having these custom allocators that would do fancy things ontop of operator new. The STL architects could see back in 1993 that this was obviously inevitable, and they'd be kicking themselves if they didn't build in support for custom memory allocators into every STL class and function.
So, in the intervening 15 years no one has every written a custom memory allocator. It could happen any day now though...
The nearly universal practice is to ignore the Allocator parameter everywhere it occurs and just leave it to its default value. So, the constructor has two "real" parameters.
Firebrand
12-12-2008, 04:39 PM
Support for STL is varied and touchy depending on the compiler you're using. For instance, new versions of Visual C++ Express edition work quite well with STL. Visual C++ 6 (IMO the last good compiler from MS despite the incomplete C++ compatibility) will choke and die with STL. My first impression is that the version of GCC you're using may be an older version that does not properly support the templates (templates and other full ANSI C++ spec syntactic sugar are not 100% complete in any compiler) that STL uses. Either upgrade your GCC to the newest release version or (if your class supports this) uses VCPPEE.
Firebrand9 added to this post, 13 minutes and 27 seconds later...
Using g++, the following code (similar to HackerX's and Josephine1012's) should work:
#include <iostream>
#include <string>
#include <vector>
int main()
{
using namespace std;
vector<string> v;
string s = "zero";
v.push_back(s);
v.push_back("one");
cout << "The first element of v is " << v[0] << endl;
cout << "The second element of v is " << v[1] << endl;
return 0;
}
I'm not sure why (so this post may not help you much) or the exact details, but initializing a vector to an STL object is problematic; I have run into the same issue when attempting to create a vector of STL maps (and, additionally, with some of my own custom classes). Rather than assigning upon initialization, use the push_back() method instead. I vaguely remember this having something to do with either copy constructors or assignment operators in classes, but I'm not entirely sure; I would actually be interested to know the reasoning for this, if anyone could explain.
It must have to do with the constructor for the STL classes. Probably (and I don't have the source to STL in front of me to verify this but I will make an educated deduction based on my experience) the head pointer or whatever initial values the STL class needs to allow it to start adding elements has not been initialized yet and is throwing an error. With templates in general the compiler only constructs it's own unique version of the class using the class and the type at compile-time and if there are issues with it's own version then they will come up in the funky, difficult-to-decipher error messages that you see. STL is notorious for this.
Firebrand9 added to this post, 3 minutes and 21 seconds later...
Could somebody tell me the best way to overload the << operator? I think what I need is a way to restrict it to a class called "Grammar". "Grammar" is included in "RandomSentenceGenerator", which has a private instance of Grammar, and also uses cout, but shouldn't use the << operator defined in "Grammar" unless what it is printing actually is a Grammar.
Put this in the Grammer class definition :
friend ostream & operator << (ostream & Out, const Grammer & The_Grammer);
Firebrand9 added to this post, 12 minutes and 48 seconds later...
[rant mode]
The STL basically just sucks. The whole template thing is basically a way to try and get #defines from C "right". Anyone who disagrees on this: take a look at the trainwreck that is vector<bool>.
Another thing: what "genius" came up with the C++ standard out?
cout << "Random syntax like this is what makes C++ hard to use."
<< "\n I mean, it sort of makes sense if you squint at it"
<< "\n 'Left Shifting' into the stream.... but not really.";
I could go on: initializer lists. The no operator constructor.
I totally agree. STL blows. I think Bjarne Stoustrup came up with something of genius with C++ but the thing everyone forgot while adopting OOP is that means Object-Oriented-Programming not Object-Obsessive-Programming. When I wrote a .3DS file reader for a 3D engine I'm working on a while back I just wrote a templated linked-list class (due to the weird chunk-based file format where if there are subobjects, there's no way to know up front how many vertices to allocate) in a few hours rather than use STL. It works the way I want, not the way the questionably insane STL implementors want and I've have zero issues with it.
vBulletin® v3.8.7, Copyright ©2000-2013, vBulletin Solutions, Inc.