Sign in to follow this  

std::vector question

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

If you intended to correct an error in the post then please contact us.

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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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]

Share this post


Link to post
Share on other sites

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

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this