를 사용하는 std::벡터로 보기에는 원시 메모리

나는'm 를 사용하여 외부 라이브러리는 어떤 시점에서 제게 원 포인터 배열의 정수 및 크기입니다.

지금 나는'd 같이 사용하는std::벡터에 액세스하고 이러한 값을 수정 장소에 보다는 오히려 그들을 액세스 하는 것으로 원 포인터입니다.

여기에는 articifial 를 들어 설명하는 포인트:

size_t size = 0;
int * data = get_data_from_library(size);   // raw data from library {5,3,2,1,4}, size gets filled in

std::vector<int> v = ????;                  // pseudo vector to be used to access the raw data

std::sort(v.begin(), v.end());              // sort raw data in place

for (int i = 0; i < 5; i++)
{
  std::cout << data[i] << "\n";             // display sorted raw data 
}

예상 출력:

1
2
3
4
5

그 이유는 내가 필요로 적용하는 알고리즘에서<알고리즘>(정렬,swaping 요소 등). 에는 데이터입니다.

다른 한편으로의 크기를 변경하는 벡터 수 없을 것이 변경되었다,그래서push_back,삭제,`삽입은 필요하지 않습에서 작동하는 벡터입니다.

나를 구성할 수 있습 벡터 데이터를 기반으로 라이브러리에서 사용할 수정하는 벡터와 데이터를 복사하시는 라이브러리,그러나는 것 두 개의 완전한 복사본는'd 을 피하기 위해 같은 데이터로 설정 될 수 있다는 정말 큰일이다.

질문에 대한 의견 (12)

C++20'sstd::span

는 경우 사용할 수 있는 C++20,사용할 수 있[std::span](https://en.cppreference.com/w/cpp/container/span 도)포인터 길이의 쌍는 사용자에게 맞으면 연속 순서의 요소입니다. 그것은 일종의std::string_view,그리고 모두가std::spanstd::string_view비유망,std::string_view읽기 보기만 가능합니다. 에서 docs:

The 템플릿 클래스의 범위는 개체를 설명하기를 참조하십시오 인접 객체의 순서와의 첫 번째 요소는 순서 에 위치한다. 범위할 수 있습 중 하나는 정도에서는 용자 시퀀스의 요소가 알려져 있고,인코딩 유형,또는 동적 정도입니다. 그래서 다음과 같은 작동: ``c++

include

include<마스터는 모든>

include<알고리즘>

int main(){ int 데이터[] = { 5, 3, 2, 1, 4 }; std::spans{데이터,5}; std::종(s.begin(),s.end()); for(자동 const i:s){ std::cout<<i<<"\n"; } return0; } Check it out[live][1] 이후`std::span`은 기본적으로 포인터 길이의,당신은 당신이 사용할 수 있는 다음과 같은 방법으로도: c++ 실제로 매우 불만족스럽다.size=0; int*데이터=get_data_from_library(size); std::spans{데이터,크기}; ` **참고:**하지 않는 모든 컴파일러 지원std::span. 검사 컴파일러를 지원하는[여기](https://en.cppreference.com/w/cpp/compiler_support). **업데이트** 할 수 없는 경우 사용하는 C++20,사용할 수 있[gsl::span](https://github.com/microsoft/GSL 도)기본적으로 기본 버전의 C++표준&#39;sstd::span`.

C++11 솔루션

제한이 있는 경우 C++11 일 기준,당신이 시도할 수 있습을 구현하 자신의 간단한범위클래스: ``c++ 템플릿<형태 T> 클래스 span{ Tptr_; std::sizet len; 공용: 범위(Tptr,std::sizet len)noexcept :ptr{ptr},len{len} {} T&operator[](int i)noexcept{ return*ptr[i]; } T const&operator[](int i)const noexcept{ return*ptr_[i]; }

std::sizet size()const noexcept{ 반 len; } Tbegin()noexcept{ 반 ptr_; } Tend()noexcept{ 반 ptr+len; } }; `` 체크아웃 C++11 버전라이브

해설 (2)
해결책

문제는std::벡터는 복사본을 만들기 위해 요소의 배열에서 당신은 그것을 초기화와 함께 그것의 소유권을 개체 포함되어 있습니다.

이를 방지하기 위해 사용할 수 있습니다조각개체에 대한 배열(즉,는 것과 비슷한std::string_view이하std::string). 당신이 쓸 수 있는 자신의array_view클래스 템플릿을 구현하의 인스턴스가 구성되어를 복용하여 원 포인터 배열's 첫번째 요소를 배열 길이:

#include 

template
class array_view {
   T* ptr_;
   std::size_t len_;
public:
   array_view(T* ptr, std::size_t len) noexcept: ptr_{ptr}, len_{len} {}

   T& operator[](int i) noexcept { return ptr_[i]; }
   T const& operator[](int i) const noexcept { return ptr_[i]; }
   auto size() const noexcept { return len_; }

   auto begin() noexcept { return ptr_; }
   auto end() noexcept { return ptr_ + len_; }
};

array_view지 않't 저장 array;그냥을 보유하고 포인터 배열의 시작 부분의 길이는 배열입니다. 따라서,array_view체는 저렴한을 구성하고를 복사합니다.

이후array_view제공begin()andend()회원 기능을 사용할 수 있는 표준 라이브러리에서 알고리즘은(예를 들어,std::종류,std::찾기,std::lower_bound,etc.) it:


#define LEN 5

auto main() -> int {
   int arr[LEN] = {4, 5, 1, 2, 3};

   array_view av(arr, LEN);

   std::sort(av.begin(), av.end());

   for (auto const& val: av)
      std::cout 
해설 (2)

때문에 알고리즘-라이브러리와 함께 작동 반복기를 유지할 수 있습니다.

에 대한 포인터 및 알려진 배열 길이

여기에서 사용할 수 있는 원 포인터로 반복기. 그들은 지원 opertations 반복기를 지원(증가 비교에 대한 평등의 가치,etc.):

``

include<마스터는 모든>

include<알고리즘>

int*get_data_from_library(int&크기){ static int data[]={5,3,2,1,4};

size=5;

데이터는 반환; }

int main() { int 크기; int*데이터=get_data_from_library(size);

std::종(데이터,데이터+크기);

for(int i=0;i<size;i++) { std::cout<<data[i]><<"\n"; } } ``

데이포인트 dirst 배열 구성원처럼 반복기 반환에 의해begin()데이터+크기포인트의 요소를 한 후에 마지막 요소의 배열은 다음과 같이 반복기를 반환한end().

에 대한 배열

여기서 당신은사용할 수 있습니다 std::begin()std::end()

``

include<마스터는 모든>

include<알고리즘>

int main() { int data[]={5,3,2,1,4};//원의 데이터 라이브러리

std::종(std::을 시작(data),std::종료(data));//원시 데이터를 정렬 장소에서

for(int i=0;i<5;i++) { std::cout<<data[i]><<"\n";//디스플레이 정렬된 원시 데이터 } } ``

그러나 유지 하는 마음에만 이 경우,데이터는`부패하지 않은 포인터이기 때문에,그 길이는 정보가 없습니다.

해설 (1)

당신이 얻을 수있는 반복기를 원 어레이 및에서 사용하는 알고리즘:

c++ int data[]={5,3,2,1,4}; std::종(std::을 시작(data),std::종료(data)); for(자가:데이터){ std::cout<<i<<std::할당 공개; }

로 작업하는 경우에는 원 포인터(ptr+크기),다음 사용할 수 있습니다 다음과 같은 기법: c++ 실제로 매우 불만족스럽다.size=0; int*데이터=get_data_from_library(size); 자동차 b=데이터 자동차 e=b+크기; std::종(b,e); 한(그것은 자동=b;it!= e;그것을++){ cout<<*it<<할당 공개; } UPD: 그러나,위의 예쁜 디자인이다. 라이브러리를 반환 우리에게 원 포인터리고 우리는't 알고 있는 근본적인 버퍼가 할당되고 사람을 무료니다.

일반적으로,발신자가 제공하는 버퍼링을 위한 함수를 채우는 데이터입니다. 는 경우에,우리는 미리 할당 벡터와 사용할 기본 버퍼 c++ std::vector<int>v; v. 크기 조정(256);//버퍼를 할당을 위해 정수 256 size_t 크기=get_data_from_library(v. 데이터를(),v.size()); //수 있는 실제 데이터입니다. 참고로 기억 realocations 또는 사본은 여기에서 이루어집니다. v. 크기 조정(size); std::종(v.begin(),v.end()); for(자가:v){ cout<<i<<할당 공개; }

할 때 사용하여 C++11 나 위에서 우리는 할 수 있습 get_data_from_library()에서 반환하는 벡터입니다. 감사를 이동하는 작업이 없을 것,메모리에 복사합니다.

해설 (4)

이제 나는'd 같이 사용하는 std::벡터에 액세스하고 이러한 값을 수정 장소에서

당신은 할 수 없습니다. 는's 지 않 whatstd::벡터이다.std::벡터리 자신의 버퍼는 항상에서 획득 할당자. 그것은 결코의 소유권 또 다른 완충기(제외에서 또 다른 벡터의 동일한 타입)으로 구성되어 있습니다.

다른 한편으로는,당신은 또한지't 필요하기 때문에...

그 이유는 내가 필요로 적용하는 알고리즘에서<알고리즘>(정렬,swaping 요소 등). 에는 데이터입니다.

그는 알고리즘에서 작동 반복기. 포인터가 반복기를 포함하는 배열을 반환합니다 지't 필요 vector:

std::sort(data, data + size);

과는 달리는 기능 템플릿에서<알고리즘>,몇 가지 도구와 같은 범위에 대한,std::작/std::엔드그리고 C++20 범위와 함께 작동하지 않습의 반복기 비록하는 동안,그들은 작업으로 용기와 같은 벡터입니다. 그것은 가능한 래퍼를 만들어 등에 대한 반복+크기는 대로 작동 범위 및 작동을 가진 이러한 도구입니다. C++20 을 소개합니다 이러한 래퍼로 표준 라이브러리:std::span.

해설 (0)

할 수 있't 이와 함께std::벡터없이 복사본을 만들.std::벡터소유하고 포인터가에서는 두건과 공간을 할당합을 통해 할당자를 제공한다.

이 있는 경우 acess 컴파일러를 지원하는 C++20 를 사용할 수 있std::스팬장이 목적입니다. 래핑 포인터와 크기로"컨테이너"있는 C++컨테이너 인터페이스입니다.

하지 않을 경우,사용할 수 있gsl::스팬어떤 표준 버전의 기반으로.

지 않는 경우't 고 싶은 가져 오기 다른 라이브러리할 수 있습 손쉽게 구현하 자신이 무엇인지에 따라 모든 기능을 다하고 있습니다.

해설 (0)

당신은 실제로수 있거의 사용std::벡터이를 위해,우월적 지위를 이용하여 사용자 정의 할당자를 기능을하는 포인터를 반환하는 메모리를 선택하십시오. 는 것't 에 의해 보장되는 표준을 일(패딩,정렬,초기화는 반환되는 값이다;당신이'd 을 가지고 가야 고통을 할당할 때 처음 크기,그리고 비 프리미티브를'd 는 또한 필요가 해킹을 당신의 생성자),그러나 실제로 기능을 충분히 되었습니다.

절대로 적다. It's ugly,놀라,해키고 불필요합니다. 표준 라이브러리는's 는 알고리즘은이미작동하도록 설계되었으로뿐만 아니라 원로 배열과 벡터입니다. 다른 답변에 대한 정보입니다.

해설 (3)

또 다른 좋은 제안에 대해std::span에서 오는[태그:c++20]그리고gsl:span,자신을 포함하여(라)범위클래스 그때까지 충분히 쉽게 이미(무료 사본):


template
struct span {
    T* first;
    size_t length;
    span(T* first_, size_t length_) : first(first_), length(length_) {};
    using value_type = std::remove_cv_t;//primarily needed if used with templates
    bool empty() const { return length == 0; }
    auto begin() const { return first; }
    auto end() const { return first + length; }
};

static_assert(_MSVC_LANG 
해설 (6)

당신이 사용할 수 있[std::reference_wrapper][1]이후 사용 가능한 C++11:


#include 
#include 
#include 
#include 

int main()
{
    int src_table[] = {5, 4, 3, 2, 1, 0};

    std::vector< std::reference_wrapper< int > > dest_vector;

    std::copy(std::begin(src_table), std::end(src_table), std::back_inserter(dest_vector));
    // if you don't have the array defined just a pointer and size then:
    // std::copy(src_table_ptr, src_table_ptr + size, std::back_inserter(dest_vector));

    std::sort(std::begin(dest_vector), std::end(dest_vector));

    std::for_each(std::begin(src_table), std::end(src_table), [](int x) { std::cout 
해설 (10)

다른 사람들이 지적으로,std::벡터있어야 합니다 기본 메모리(의 짧은 듣는 사용자 정의 할당자)그래서 수 있't 를 사용합니다.

다른 사람들도 좋 c++20's 범위,그러나 분명히 필요로 하는 c++20.

내가 권하고 싶[span-lite][1]span. 을 인용하는's 자막:

span lite-C++20 같은 범위에 대한 C++로 98,C++11 그 후에 단일 파일의 헤더에만 라이브러리

제공하는 비유와 가변 전망(로에 당신을 변화시킬 수 있는 요소와 그들의 순서만 그들을 삽입)및 따옴표가 말하는 때에는 없는 종속성과 작품에서 가장 컴파일러입니다.

귀하의 예:


#include 
#include 
#include 

#include 

static int data[] = {5, 1, 2, 4, 3};

// For example
int* get_data_from_library()
{
  return data;
}

int main ()
{
  const std::size_t size = 5;

  nonstd::span v{get_data_from_library(), size};

  std::sort(v.begin(), v.end());

  for (auto i = 0UL; i < v.size(); ++i)
  {
    std::cout 
해설 (0)