Проблема с «перемещаемыми типами» в VC ++ 2010 - PullRequest
10 голосов
/ 21 апреля 2010

Я недавно установил Visual Studio 2010 Professional RC, чтобы опробовать его и протестировать несколько функций C ++ 0x, реализованных в VC ++ 2010.

Я создал std::vector из std::unique_ptr, без каких-либо проблем. Однако, когда я пытаюсь заполнить его, передав временные значения в push_back, компилятор жалуется, что конструктор копирования unique_ptr является закрытым. Я попытался вставить lvalue, переместив его, и он работает просто отлично.

#include <utility>
#include <vector>

int main()
{
    typedef std::unique_ptr<int> int_ptr;

    int_ptr pi(new int(1));

    std::vector<int_ptr> vec;

    vec.push_back(std::move(pi));      // OK
    vec.push_back(int_ptr(new int(2))); // compiler error
}

Как оказалось, проблема не в unique_ptr и vector::push_back, а в том, как VC ++ разрешает перегрузки при работе со значениями, как показано в следующем коде:

struct MoveOnly
{
    MoveOnly() {}
    MoveOnly(MoveOnly && other) {}

private:

    MoveOnly(const MoveOnly & other);
};

void acceptRValue(MoveOnly && mo) {}

int main()
{
    acceptRValue(MoveOnly()); // Compiler error
}

Компилятор жалуется, что конструктор копирования недоступен. Если я сделаю это общедоступным, программа скомпилируется (хотя конструктор копирования не определен).

Я что-то не так понял относительно ссылок на rvalue, или это (возможно, известная) ошибка в реализации этой функции в VC ++ 2010?

Ответы [ 3 ]

12 голосов
/ 26 апреля 2010

К сожалению, / Za глючит. Он выполняет проверку доступности elided-copy-constructor-accessibility, когда не должен (привязка ссылок на rvalue не вызывает конструкторов копирования, даже теоретически). В результате / Za не должен использоваться.

Стефан Т. Лававей, разработчик библиотек Visual C ++ (stl@microsoft.com)

1 голос
/ 21 апреля 2010

Я заметил, что у меня отключены языковые расширения (\ Za). При включенных расширениях код корректно компилируется. Я все еще думаю, что это ошибка, поскольку представленный здесь код является совершенно стандартным (насколько я знаю) и не зависит от каких-либо расширений Microsoft.

1 голос
/ 21 апреля 2010

Прежде всего, вам нужно закрыть ):

vec.push_back(int_ptr(new int(2))) ; // ошибка компилятора

Теперь у меня нет ошибки компиляции ни в первом, ни во втором случае.

Я использую Visual Studio 2010 Beta.

...