std::vector question

Started by
7 comments, last by joanusdmentia 16 years, 7 months ago
After reading "I'm stupid", "An example of why I'm stupid", and "Information to help from staying stupid", I still stuck on stupid [smile]

void DrawText(LPDXUFONT font, const std::string& text)
{
  std::vector<char> buffer(text.c_str(), text.c_str() + text.length() + 1);

  DXUDrawText(font, &buffer[0]);
}
Why can't I just put text.length() + 1 instead of text.c_str() + text.length() + 1?

Beginner in Game Development?  Read here. And read here.

 

Advertisement
Because you need begin and end iterators, rather than begin and count?

text.c_str() + text.length() + 1
Results in Pointer + Length + 1, which is char *, which in turn gets used as iterator.

text.length() + 1
However is just an int.

I don't remember copy constructor right now, but most containers use iterators as parameters.

Given the syntax of constructor:
template <class InputIterator>vector(InputIterator, InputIterator)
, you need to provide absolute pointers (which will be treated as iterators).
The second parameter is the end, not the length.
Ra
I may have the answer to my own question.

That version of vector takes an iterator that points to the begin of the array and an iterator that points to the end of the array. Therefore, it'll need the address of the first element in the array and the address of the last element in the array. The only (correct) way of the end address is: &element[0] + sizeof (char)*number of chars. Hence text.c_str + text.length() +1 (+1 to hold the '\0').

Right?

edit: it seems I got answer while I was typing up the answer myself [smile] Thanks guys.

Beginner in Game Development?  Read here. And read here.

 

That's using this constructor for std::vector:
template <class InputIterator> vector ( InputIterator first, InputIterator last, const Allocator& = Allocator() );    Iteration constructor: Iterates between first and last, setting a copy of each of the sequence of elements as the content of the container.


Basically, You need to provide two iterators(/pointers), a start and an end. So, text.c_str() gives you the start pointer, but text.length() + 1 would just be an integer. Instead, you need an end pointer, which is to say text.c_str() + text.length() + 1.

Edit: Too slow x 3.

Edit2: While we're one the subject, why even use the buffer over, say:
void DrawText(LPDXUFONT font, const std::string& text){  DXUDrawText(font, text.c_str());}
I don't have my nice reference with me, but going off the web reference...

(Best guess):

Because text.length() + 1 is not a InputIterator for std::vector<char>, it's a size_t.

The constructors for std::vector are...

vector()vector(size_type)vector(size_type, const T&)vector(const vector<T>&)vector(InputIterator, InputIterator)


So, with two parameters that leaves #3 and #5. #3 isn't good since text.c_str() returns a const char * which is incompatable with a size_type (I think). The type of an InputIterator is probably a char * since that's generally how those things go. Likely compatable.

text.length()+1 is a size_t plus a constant, making another size_t

A const char * plus a size_t plus a constant is another const char * via pointer arithmetic. Likely compatible with constructor #5.

[edit: super, duper too slow.]
Remember that std::string also has begin() and end() members for getting the respective iterators, so you could just use that instead.
std::vector<char> buffer(text.begin(), text.end());
"Voilà! In view, a humble vaudevillian veteran, cast vicariously as both victim and villain by the vicissitudes of Fate. This visage, no mere veneer of vanity, is a vestige of the vox populi, now vacant, vanished. However, this valorous visitation of a bygone vexation stands vivified, and has vowed to vanquish these venal and virulent vermin vanguarding vice and vouchsafing the violently vicious and voracious violation of volition. The only verdict is vengeance; a vendetta held as a votive, not in vain, for the value and veracity of such shall one day vindicate the vigilant and the virtuous. Verily, this vichyssoise of verbiage veers most verbose, so let me simply add that it's my very good honor to meet you and you may call me V.".....V
Quote:Original post by joanusdmentia
Remember that std::string also has begin() and end() members for getting the respective iterators, so you could just use that instead.
std::vector<char> buffer(text.begin(), text.end());


But that will not null-terminate the buffer.
Arguing on the internet is like running in the Special Olympics: Even if you win, you're still retarded.[How To Ask Questions|STL Programmer's Guide|Bjarne FAQ|C++ FAQ Lite|C++ Reference|MSDN]
Quote:Original post by dalleboy
Quote:Original post by joanusdmentia
Remember that std::string also has begin() and end() members for getting the respective iterators, so you could just use that instead.
std::vector<char> buffer(text.begin(), text.end());


But that will not null-terminate the buffer.


True, but an extra call to buffer.push_back('\0'); is clearer and less error prone than text.c_str() + text.length() + 1, which clearly isn't clear given the existence of this thread. [smile]
"Voilà! In view, a humble vaudevillian veteran, cast vicariously as both victim and villain by the vicissitudes of Fate. This visage, no mere veneer of vanity, is a vestige of the vox populi, now vacant, vanished. However, this valorous visitation of a bygone vexation stands vivified, and has vowed to vanquish these venal and virulent vermin vanguarding vice and vouchsafing the violently vicious and voracious violation of volition. The only verdict is vengeance; a vendetta held as a votive, not in vain, for the value and veracity of such shall one day vindicate the vigilant and the virtuous. Verily, this vichyssoise of verbiage veers most verbose, so let me simply add that it's my very good honor to meet you and you may call me V.".....V

This topic is closed to new replies.

Advertisement