2

I'm new to C++ and trying to understand how declaring vectors work. Below are some examples:

std::vector j;
std::vector<char[256]> k;
std::vector<double> v;
std::vector<std::vector<int>> s;

My thoughts are only the std::vector<double> v is legal and I tested it myself such that only this line of code compiles without error. But apparently all of these are allowed. Can someone please explain how the others work and why the others when I run it are giving me errors?

So if I run this code:

#include <iostream>
#include <vector>

int main() {

//std::vector j;
std::vector<char[256]> k;
std::vector<double> v;
std::vector<std::vector<int>> s;
}

I'm getting a bunch of errors when I compile (I'm using Atom g++ compiler package with Xcode):

C++ - test.cpp:12
In file included from <built-in>:2:
In file included from /Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/iostream:37:
In file included from /Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/ios:215:
In file included from /Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/__locale:14:
In file included from /Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/string:504:
In file included from /Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/string_view:175:
In file included from /Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/__string:56:
In file included from /Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/algorithm:643:
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/memory:1880:61: error: object expression of non-scalar type 'char [256]' cannot be used in a pseudo-destructor expression
    _LIBCPP_INLINE_VISIBILITY void destroy(pointer __p) {__p->~_Tp();}
                                                         ~~~^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/memory:1742:18: note: in instantiation of member function 'std::__1::allocator<char [256]>::destroy' requested here
            {__a.destroy(__p);}
                 ^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/memory:1595:14: note: in instantiation of function template specialization 'std::__1::allocator_traits<std::__1::allocator<char [256]> >::__destroy<char [256]>' requested here
            {__destroy(__has_destroy<allocator_type, _Tp*>(), __a, __p);}
             ^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/vector:426:25: note: in instantiation of function template specialization 'std::__1::allocator_traits<std::__1::allocator<char [256]> >::destroy<char [256]>' requested here
        __alloc_traits::destroy(__alloc(), _VSTD::__to_raw_pointer(--__soon_to_be_end));
                        ^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/vector:369:29: note: in instantiation of member function 'std::__1::__vector_base<char [256], std::__1::allocator<char [256]> >::__destruct_at_end' requested here
    void clear() _NOEXCEPT {__destruct_at_end(__begin_);}
                            ^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/vector:463:9: note: in instantiation of member function 'std::__1::__vector_base<char [256], std::__1::allocator<char [256]> >::clear' requested here
        clear();
        ^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/vector:495:5: note: in instantiation of member function 'std::__1::__vector_base<char [256], std::__1::allocator<char [256]> >::~__vector_base' requested here
    vector() _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
    ^
/Users/moeheinag/Desktop/C++/UIUC/Course1/test.cpp:7:24: note: in instantiation of member function 'std::__1::vector<char [256], std::__1::allocator<char [256]> >::vector' requested here
std::vector<char[256]> k;
                       ^
1 error generated.
[Finished in 0.375s]
Bathsheba
  • 231,907
  • 34
  • 361
  • 483

2 Answers2

4

A fixed array template for a std::vector was not allowed up to and including C++03. This is because arrays are neither CopyAssignable nor CopyConstructible.

So std::vector<char[256]> k; is invalid pre-C++11. From C++11 onwards you can declare such a type, although you'll have difficulty using such an instantiation - e.g. push_back will not work, but emplacements will. Using std::array<char, 256> in place of char[256] is an obvious fix.

Note also that pre-C++11, std::vector<std::vector<int>> s; is invalid too - you need a space between >> otherwise the compiler treats >> as a bitwise shift!

In other words, upgrade to C++11.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
0

but apparently all of these are allowed. Can someone please explain how the others work?

std::vector j; // invalid
std::vector<char[256]> k; // ok
std::vector<double> v; // ok
std::vector<std::vector<int>> s; // ok

Actually the first one is invalid, all the others all valid, because std::vector is templated. You must provide the type on declaration.

artm
  • 17,291
  • 6
  • 38
  • 54