vС++ 2010/2012:std::vector структуры, содержащей ошибку компилятора unique_ptr

StackOverflow https://stackoverflow.com//questions/11697994

Вопрос

Следующий код генерирует ошибку компилятора ниже (после кода), но не в том случае, если вектор содержит unique_ptr напрямую (см. строки кода с комментариями).Есть идеи, почему?

Вопрос больше касается блока кода в блоке "#if 1", блок "#else" генерирует ошибку (после замены "#if 1" на "#if 0"), которая аналогична, но более ожидаема. .

// MoveSemantics.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <memory>
#include <vector>

typedef std::unique_ptr<int> upi;

struct S
{
    S() : p(new int(123)) {}
    S(S&& s) : p( std::move(s.p) ) {} // NB: the move constructor is supposed to be used? (but not)
    upi p;
};

#if 1
void test()
{
    //std::vector<S> vs; // Okay
    //std::vector<upi> vupi(10); // Okay
    std::vector<S> vs(10); // Error! why in the hell does the compiler want to generate a copy constructor here??
}
#else
void test()
{
    std::vector<S> vs;

    vs.push_back( S() );
    const S& s = vs.front();
    //S& s = vs.front(); // fine!
    S s1 = std::move(s); // Error, but expected
}
#endif
int _tmain(int argc, _TCHAR* argv[])
{
    return 0;
}

Ошибка компилятора:

1> error C2248: 'std::unique_ptr<_Ty>::operator =' : cannot access private member declared in class 'std::unique_ptr<_Ty>'
1>          with
1>          [
1>              _Ty=int
1>          ]
1>          c:\program files\microsoft visual studio 11.0\vc\include\memory(1435) : see declaration of 'std::unique_ptr<_Ty>::operator ='
1>          with
1>          [
1>              _Ty=int
1>          ]
1>          This diagnostic occurred in the compiler generated function 'S &S::operator =(const S &)'
Это было полезно?

Решение

Это похоже на ошибку в вашем std::lib.Я уверен, что он появился здесь из-за истории развития vector Спецификация.

В С++98/03 vector был этот конструктор:

explicit vector(size_type n, const T& value = T(), const Allocator& = Allocator());

И спецификация заключалась в том, что T будет создан по умолчанию один раз, а затем скопирован n раз при вызове с двумя последними аргументами по умолчанию.

В C++11 это было изменено на:

explicit vector(size_type n);
vector(size_type n, const T& value, const Allocator& = Allocator());

Спецификация второго конструктора не изменилась.Но первый сделал:Он должен построить по умолчанию T n раз, а не копировать (или перемещать) его вообще.

Я ожидал, что в сообщении об ошибке будет указано, что удаленный или личный конструктор копирования из unique_ptr использовался.Это означало бы, что vector следовал спецификации C++98/03 и просто еще не обновлялся.

Но так как диагностика жалуется на unique_ptr's копирование задания вместо этого это выглядит как vector обновился, но некорректно.Похоже, он использует эту подпись из C++98/03:

explicit vector(size_type n, const T& value = T(), const Allocator& = Allocator());

и построение по умолчанию n Ts, а затем присваивая value к тем n Tх.

Другие советы

Вы не включали оператор назначения перемещения, который является частью требований vector, только конструктор движения.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top