Я ищу, чтобы создать тип, который может быть инициализирован с присваиванием из другого типа, но не может быть скопирован. Идея аналогична идее интеллектуального указателя с заданной областью в том, что я хочу, чтобы объект этого типа владел ресурсом в течение его времени жизни, но я также хочу иметь возможность использовать синтаксис присваивания. Итак, в кратком изложении, это то, что я хочу:
T x = new U; // allowed
T y(new U); // allowed
T z = x; // not allowed
T x2(x) // not allowed
Это то, что я пытался до сих пор …
#include <boost/noncopyable.hpp>
class U {};
class T : boost::noncopyable {
public:
T(U *p) : p_(p) {
}
~T() {
delete p_;
}
operator bool() const { return p_ != 0; }
private:
U *p_;
};
int main() {
T x = new U; // allowed
T y(new U); // allowed
//T z = x; // not allowed
//T x2(x) // not allowed
}
что, к сожалению, приводит к ошибке:
$ g ++ test.cc -o test /usr/include/boost/noncopyable.hpp: в копии
конструктор ‘T :: T (const T&) ‘: /usr/include/boost/noncopyable.hpp:27:7:
ошибка: ‘boost :: noncopyable _ :: noncopyable :: noncopyable (const
повышение :: noncopyable _ :: noncopyable&) ‘является частным test.cc:6:30: ошибка:
в этом контексте test.cc: в функции ‘int main ()’: test.cc:20:12:
Примечание: синтезированный метод ‘T :: T (const T&) ‘сначала требуется здесь
ПРИМЕЧАНИЕ. Функции перемещения в C ++ 11 для меня неактивны, так как они должны быть скомпилированы с относительно старой версией gcc, которая не поддерживает C ++ 11.
Из-за отсутствия поддержки C ++ 11, я не уверен, что есть «хорошее» решение. Но я решил спросить.
Если мое понимание комментариев верно — вы хотите что-то подобное:
U* create_T() { return new U; }
if (T t = create_T())
{
// do something with t
}
Проблема здесь, уже упоминавшаяся в комментариях: это синтаксис T t = u просто вызывает конструктор копирования. Если ты типа T это эквивалентно: T t(u), Если uкак в вашем примере, имеет другой тип, преобразуемый в T (here by T::T(U*)) то на самом деле это так: T t(T(u)), Здесь у вас есть конструктор копирования, на который жалуется компилятор.
Там нет решения, потому что это не является действительным if синтаксис:
if (T i(create_T())) {}
Однако я не написал бы все это без хорошего совета;)
Вы можете забыть о проблемах с конструктором копирования следующим синтаксисом:
if (U* u = create_T()) {
T t(u);
....
}
КСТАТИ, std::auto_ptr имеет ту же проблему, что и ваш T тип. Просто добавьте явное к вашему T(U*) конструктор, и вы увидите сходство с auto_ptr:
class U {};
class T : boost::noncopyable {
public:
explicit T(U *p) : p_(p) {
}
~T() {
delete p_;
}
private:
U *p_;
};
int main() {
T x = new U; // allowed
T y(new U); // allowed
std::auto_ptr<U> a = new U;
std::auto_ptr<U> b(new U);
}
Результаты в:
prog.cpp:25: error: conversion from ‘U*’ to non-scalar type ‘T’ requested
prog.cpp:27: error: conversion from ‘U*’ to non-scalar type ‘std::auto_ptr<U>’ requested
Вот мой ideone изучение…
Других решений пока нет …