Public Group

# std::vector question

This topic is 3944 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

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?

##### Share on other sites
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).

##### Share on other sites
The second parameter is the end, not the length.

##### Share on other sites
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.

##### Share on other sites
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());}

##### Share on other sites
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.]

##### Share on other sites
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());

##### Share on other sites
Quote:
 Original post by joanusdmentiaRemember that std::string also has begin() and end() members for getting the respective iterators, so you could just use that instead.std::vector buffer(text.begin(), text.end());

But that will not null-terminate the buffer.

##### Share on other sites
Quote:
Original post by dalleboy
Quote:
 Original post by joanusdmentiaRemember that std::string also has begin() and end() members for getting the respective iterators, so you could just use that instead.std::vector 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]

1. 1
2. 2
Rutin
24
3. 3
JoeJ
19
4. 4
5. 5

• 17
• 40
• 23
• 13
• 13
• ### Forum Statistics

• Total Topics
631729
• Total Posts
3001918
×