Как легально объявить векторные переменные в C ++? - PullRequest
1 голос
/ 05 августа 2020

Я новичок в C ++ и пытаюсь понять, как работает объявление векторов. Ниже приведены некоторые примеры:

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

Я считаю, что только std::vector<double> v является законным, и я сам проверил его, так что только эта строка кода компилируется без ошибок. Но, видимо, все это разрешено. Может кто-нибудь объяснить, как работают другие и почему другие, когда я запускаю его, выдают мне ошибки?

Итак, если я запустил этот код: ошибки при компиляции (я использую пакет компилятора Atom g ++ с 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]

Ответы [ 2 ]

5 голосов
/ 05 августа 2020

Фиксированный шаблон массива для std::vector не допускался вплоть до C ++ 03 включительно. Это связано с тем, что массивы не являются ни CopyAssignable , ни CopyConstructible .

Таким образом, std::vector<char[256]> k; является недопустимым до C ++ 11. Начиная с C ++ 11, вы можете объявлять такой тип, хотя у вас возникнут трудности с использованием такого экземпляра - например, push_back не будет работать, но места размещения будут. Использование std::array<char, 256> вместо char[256] - очевидное исправление.

Обратите внимание, что pre-C ++ 11, std::vector<std::vector<int>> s; тоже недействителен - вам нужен пробел между >>, иначе компилятор обработает >> как побитовый сдвиг!

Другими словами, обновитесь до C ++ 11.

1 голос
/ 05 августа 2020

но очевидно все это разрешено. Может кто-нибудь объяснить, как работают другие?

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

На самом деле первый недействителен, все остальные действительны, потому что std :: vector является шаблоном. Вы должны указать тип в объявлении.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...