Проблема с "типами только для перемещения" в VС++ 2010

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

Я создал экземпляр std::vector of 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, но способ, которым VС++ разрешает перегрузки при работе с rvalues, как показано в следующем коде:

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

private:

    MoveOnly(const MoveOnly & other);
};

void acceptRValue(MoveOnly && mo) {}

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

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

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

Ответ 1

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

Стефан Т. Лававей, разработчик библиотек Visual С++ ([email protected])

Ответ 2

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

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

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

Я использую бета-версию Visual Studio 2010.

Ответ 3

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