2014-12-10 2 views
0

Я использую DenseCRF библиотеку, и я хотел, чтобы создать вектор класса этого объекта, но я получаю следующее сообщение об ошибке:Создание вектора не-Copyable объектов

/usr/include/c++/4.6/ext/new_allocator.h:108:9: error: no matching function for call to ‘DenseCRF::DenseCRF(const DenseCRF&)’ 
/densecrf2/include/densecrf.h:48:2: note: no known conversion for argument 1 from ‘const DenseCRF’ to ‘DenseCRF&’ 

Это какой класс DenseCRF. ч выглядит следующим образом:

/**** DenseCRF ****/ 
class DenseCRF{ 
protected: 
    // Number of variables and labels 
    int N_, M_; 

    // Store the unary term 
    UnaryEnergy * unary_; 

    // Store all pairwise potentials 
    std::vector<PairwisePotential*> pairwise_; 

    // Don't copy this object, bad stuff will happen 
    DenseCRF(DenseCRF & o){} 
public: 
    // Create a dense CRF model of size N with M labels 
    DenseCRF(int N, int M); 
    virtual ~DenseCRF(); 

} 

Это утонченный вариант denseCRF.h и ошибки, что указывает на проблему с denseCRF.h: 48, относится к строке 14 в этом фрагменте кода:

DenseCRF(DenseCRF & o){} 

В основной программе, я пытаюсь создать вектор этого класса, но как только я хочу puch_back экземпляра объекта, он поднимает выше ошибки:

std::vector<DenseCRF> crf_vec; 
DenseCRF crf(W, H); 
crf_vec.push_back(crf); 

Я гугл немного и понял, что Мне может понадобиться определить конструктор копирования, но не знаю, как и где. Может ли кто-нибудь помочь мне с этой проблемой?

Спасибо!

P.S. Имеет ли этот вопрос какое-либо отношение к комментариям авторов в строке 13?

+5

Есть ли «Не копировать этот объект, плохой материал произойдет» недостаточно ясно? –

+0

A 'std :: vector ' нуждается в 'T', чтобы обеспечить правильный конструктор копирования, как указано в [справочной документации] (http://en.cppreference.com/w/cpp/container/vector). –

+0

@ πάνταῥεῖ это требование было смягчено в C++ 11 –

ответ

2

Возможно простой, что нужно сделать будет определить

std::vector<std::shared_ptr<DenseCRF>> crf_vec;

вместо этого. Затем используйте

crf_vec.push_back(new DenseCRF(W, H));

std::shared_ptr является смарт-указатель. Он будет delete класс, когда вектор выходит за пределы области видимости, и все другие интеллектуальные указатели, ссылающиеся на объект, также выходят за рамки. Преимущество такого подхода заключается в том, что std::shared_ptrимеет, имеет конструктор копирования, поэтому его можно использовать в std::vector.

Существует альтернатива: использование установка. Но это сложнее.

(Кроме того, вы можете заменить DenseCRF(DenseCRF & o){} с DenseCRF(DenseCRF&) = delete;. Это явное удаление конструктора копирования.)

+0

Спасибо, но когда я пытаюсь использовать std :: shared_ptr, включив , он вызывает ошибку, которую «std :: shared_ptr» не был объявлен в этой области. – Monaj

+0

вы можете попробовать std :: tr1 :: shared_ptr < ... > или добавить -std = C++ 11 в компилятор –

+0

@ user3517598 Используете ли вы GCC 4.6? Не забудьте указать '-std = C++ 0x'. –

1

Если ваш компилятор поддерживает C++ 11, то вы можете иметь вектор без копируемыми, не связанные с движимыми объектами:

// create empty vector. Since it cannot be moved we have to allocate memory first 
std::vector<DenseCRF> vec; 
vec.reserve(1000); 

// append an item, constructing in-place 
vec.emplace_back(W, H); 

Структура DenseCRF, безусловно, движимая, по концепции; поэтому вы можете попросить авторов реализовать семантику перемещения (или сделать это самостоятельно, если она является открытым исходным кодом). Это будет означать, что вам не нужно жестко задавать ограничение по размеру вектора.

+0

Спасибо Мэтту, однако он не позволяет мне резервировать память из-за той же ошибки, что и раньше: 'отсутствие подходящей функции для вызова DenseCRF :: DenseCRF (DenseCRF)'. Это пакет с открытым исходным кодом, но я не совсем уверен, как реализовать семантику перемещения. Наверное, мне нужен какой-то гуглинг! – Monaj

+0

@ user3517598 ваш компилятор может не поддерживать C++ 11 правильно, попробуйте обновить до последней версии –

Смежные вопросы