C ++ x0 unique_ptr GCC 4.4.4 - PullRequest
       1

C ++ x0 unique_ptr GCC 4.4.4

4 голосов
/ 21 сентября 2010

Я пытаюсь использовать unique_ptr из C ++ x0, выполнив

#include <memory> 

и выполнив команду -std = c ++ 0x, однако она выдает много ошибок, так какпример.

/usr/lib/gcc/x86_64-redhat-linux/4.4.4/../../../../include/c++/4.4.4/bits/unique_ptr.h:214: error: deleted function ‘std::unique_ptr<_Tp, _Tp_Deleter>::unique_ptr(const std::unique_ptr<_Tp, _Tp_Deleter>&) [with _Tp = Descriptor, _Tp_Deleter = std::default_delete<Descriptor>]’

ОБНОВЛЕНИЕ **** Это то, что я пытаюсь сделать, я удалил typedefs, чтобы вы могли четко видеть типы

static std::unique_ptr<SomeType> GetSomeType()
{
    std::unique_ptr<SomeType> st("Data","Data2",false);

    std::unique_ptr<OtherType> ot("uniportantconstructor data");

    st->Add(ot);

    return st;

}

//Public method of SomeType
  void Add(std::unique_ptr<OtherType> ot)
  {
    //otmap is std::map<std::string,std::unique_ptr<OtherType> >
    //mappair is std::Pair<std::string,std::unique_ptr<OtherType> >
     otMap.Insert(mappair(ot->name(),ot)); 
  }

ОБНОВЛЕНИЕ:

Если в моем классе SomeType есть метод, который возвращает элемент с карты (используя ключ), скажем

std::unique_ptr<OtherType> get_othertype(std::string name)
{
   return otMap.find(name);
}

, который гарантирует, что вызывающая сторона получит указатель на тот, что на карте, а некопия

Ответы [ 3 ]

4 голосов
/ 22 сентября 2010
std::unique_ptr<OtherType> ot("unimportant constructor data");
st->Add(ot);

Вы не можете передать lvalue функции, принимающей unique_pointer, потому что unique_pointer не имеет конструктора копирования.Вы должны либо переместить lvalue (чтобы привести его к xvalue), либо передать prvalue:

// pass an xvalue:
std::unique_ptr<OtherType> ot("unimportant constructor data");
st->Add(std::move(ot));
// note: ot is now empty

// pass a prvalue:
st->Add(std::unique_ptr<OtherType>("unimportant constructor data"));

Внутри метода Add все немного сложнее.Во-первых, вы должны перейти от ot, потому что формальные параметры всегда являются lvalues ​​(так как они имеют имена).Во-вторых, вы не можете перейти от ot и получить ot->name() в качестве аргументов к функции mappair, потому что порядок вычисления аргументов в C ++ не определен.Таким образом, мы должны получить ot->name() в отдельном выражении, прежде чем перейти от ot:

void Add(std::unique_ptr<OtherType> ot)
{
    auto name = ot->name();
    otMap.Insert(mappair(name, std::move(ot))); 
}

Надеюсь, это поможет.Обратите внимание, что ни при каких (нормальных) обстоятельствах два объекта unique_ptr не могут указывать на одно и то же.Если вам нужна эта функциональность, unique_ptr - это не то, что вам нужно.

4 голосов
/ 21 сентября 2010

Похоже, вы пытаетесь использовать конструктор копирования.Там нет ни одного.Если ваш код вызова выглядит следующим образом:

T *ptr = /* whatever */;
std::unique_ptr<T> up = ptr;

Вы должны изменить вторую строку следующим образом:

std::unique_ptr<T> up (ptr);

Исходная версия (в основном) неявно превращает назначение в:

std::unique_ptr<T> up (std::unique_ptr<T>(ptr));

Конструктор копирования удален.«Удаленная функция» - это язык C ++ 0x для явного удаления неявной специальной функции-члена.В этом случае конструктор копирования.

1 голос
/ 22 сентября 2010

Как сказал @Steve, вы, вероятно, используете конструктор копирования, unique_ptr не поддерживает семантику копирования, если вы хотите переместить в значение другого unique_ptr, вам нужно move это.

 unique_ptr<T> other = std::move(orig); // orig is now null
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...