ᴘᴀɴᴀʏɪᴏᴛɪs
ᴘᴀɴᴀʏɪᴏᴛɪs

Reputation: 7529

Using std::copy to copy into an std::deque

I have a C-style array unsigned char Temp[SERVER_BUFFER_SIZE] and I want to copy it into an std::deque at the end ( more like append it)

std::deque<unsigned char>* buffer = new std::deque<unsigned char>();
std::copy(Temp[0], Temp[SERVER_BUFFER_SIZE], buffer->cend());

And I'm getting a lot of errors like these:

Error 4 error C2825: '_Iter': must be a class or namespace when followed by '::' c:\program files (x86)\microsoft visual studio 12.0\vc\include\xutility 371 1 a Error 5 error C2039: 'iterator_category' : is not a member of '`global namespace'' c:\program files (x86)\microsoft visual studio 12.0\vc\include\xutility 371 1 a Error 9 error C2825: '_Iter': must be a class or namespace when followed by '::' c:\program files (x86)\microsoft visual studio 12.0\vc\include\xutility 372 1 a Error 12 error C2602: 'std::iterator_traits<_InIt>::value_type' is not a member of a base class of 'std::iterator_traits<_InIt>' c:\program files (x86)\microsoft visual studio 12.0\vc\include\xutility 372 1 a

Upvotes: 1

Views: 6252

Answers (4)

dau_sama
dau_sama

Reputation: 4357

Here's how I'd do it

#include <iostream>
#include <deque>
#include <iterator>

int main()
{
  const size_t SERVER_BUFFER_SIZE = 6;
  unsigned char Temp[SERVER_BUFFER_SIZE] = "Hello";

  std::deque<unsigned char> buffer(Temp, Temp+SERVER_BUFFER_SIZE);

  for ( auto c : buffer ) 
    std::cout << c;
}

I construct it with a range, good thing, it actually emplace values in the deck. If you had big ojects instead of chars, it would be faster than your approach. protip: Don't use raw pointers where they're not needed. It's bad practice in C++.

Upvotes: 1

Dimitrios Bouzas
Dimitrios Bouzas

Reputation: 42929

You don't need std::copy to do this with std::deque. std::deque has member function std::deque::insert and you could append a range to it in the following manner:

#include <iostream>
#include <deque>
#include <memory>

int main() {
  std::deque<unsigned char> dq;
  unsigned char buf[] = { 1, 2, 3, 4 };

  dq.insert(dq.end(), buf, buf + 4);

  for (auto i : dq) std::cout << i << " ";
  std::cout << std::endl;

  return 0;
}

Better off, if c++11 is an option, don't use raw pointers and instead use smart pointer like std::unique_ptr:

#include <iostream>
#include <deque>
#include <memory>

int main() {
  std::unique_ptr<std::deque<unsigned char>> dq(new std::deque<unsigned char>);
  unsigned char buf[] = {1, 2, 3, 4};

  dq->insert(dq->end(), buf, buf + 4);

  for(auto i : *dq) std::cout << i << " ";
  std::cout << std::endl;

  return 0;
}

Upvotes: 3

Vlad from Moscow
Vlad from Moscow

Reputation: 311068

I do not see any sense to allocate buffer in the heap. Nevertheless the valid code will look like

std::deque<unsigned char>* buffer = new std::deque<unsigned char>();
std::copy( Temp, Temp + SERVER_BUFFER_SIZE, std::back_inserter( *buffer ) );

Here is a demonstrative program

#include <iostream>
#include <deque>
#include <iterator>

int main() 
{
    const size_t SERVER_BUFFER_SIZE = 6;
    unsigned char Temp[SERVER_BUFFER_SIZE] = "Hello";

    std::deque<unsigned char> *buffer = new std::deque<unsigned char>();

    std::copy( Temp, Temp + SERVER_BUFFER_SIZE, std::back_inserter( *buffer ) );

    for ( unsigned char c : *buffer ) std::cout << c;
    std::cout << std::endl;

    delete buffer;

    return 0;
}

The output is

Hello

Upvotes: 2

Barry
Barry

Reputation: 303377

Error tells you what you're doing wrong. std::copy takes iterators and you are giving it chars. Temp[0] and Temp[SERVER_BUFFER_SIZE] are just unsigned char.

But you don't need std::copy, deque itself takes a two-iterator constructor:

std::deque<unsigned char>* buffer = new std::deque<unsigned char>(Temp, 
                                                Temp + SERVER_BUFFER_SIZE);

or just:

std::deque<unsigned char> buffer(Temp, Temp + SERVER_BUFFER_SIZE);

Upvotes: 4

Related Questions