Учитывая следующий код:
#include <boost/noncopyable.hpp>
enum Error { ERR_OK=0 };
struct Filter : private boost::noncopyable
{
Filter() {}
virtual ~Filter() {}
virtual int filter(int* data) const = 0;
};
struct SpecialFilter : public Filter, private boost::noncopyable
{
inline SpecialFilter(unsigned int min, unsigned int max) : min(min), max(max) {}
virtual ~SpecialFilter() {}
virtual int filter(int* data) const
{
// ...
return ERR_OK;
}
unsigned int min;
unsigned int max;
};
struct AClass
{
AClass() {}
AClass(const AClass& other) {}
~AClass() {}
int specialFilter(int channel, int minThreshold, int maxThreshold)
{
// ...
return filter(channel, SpecialFilter(123, 321));
}
int filter(int channel, const Filter& filter)
{
// ...
return ERR_OK;
}
};
Мой компилятор (GCC 4.2) жалуется:
- warning: direct base ‘boost::noncopyable_::noncopyable’ inaccessible in ‘SpecialFilter’ due to ambiguity
- noncopyable.hpp: In copy constructor ‘Filter::Filter(const Filter&)’:
- noncopyable.hpp:27: error: ‘boost::noncopyable_::noncopyable::noncopyable(const boost::noncopyable_::noncopyable&)’ is private
- synthezised method first required here: [return filter(channel, SpecialFilter(123, 321));]
Но я не вызываю конструктора копии!
Вы никогда не вызываете конструктор копирования. Конструктор копирования всегда неявно вызывается компилятором. Поэтому вам нужно научиться распознавать ситуации, когда он может быть вызван.
Когда вы прикрепляете ссылку на константу к временному объекту
...
return filter(channel, SpecialFilter(123, 321));
...
, компилятор имеет право выполнить копию временного объекта и потребовать доступный конструктор копии ( даже если на самом деле он не будет вызван). Это то, что является причиной проблемы в вашем случае.
Другими словами, когда вы делаете какой-то тип не копируемым, вы также отказываетесь от возможности прикреплять ссылки на константы к временным объектам этого типа.
Во-первых, удалите частное производное от SpecialFilter - в этом нет необходимости, так как Filter уже не копируется. Вот почему я считаю такие решения, как boost :: non_copyable, плохой идеей - есть более простые способы сказать, что вам не нужны копии.
Во-вторых, хотя я не уверен, что это ваша проблема, C ++ говорит, что публичный конструктор копирования должен быть доступен компилятору при нескольких обстоятельствах, , даже если компилятор фактически не использует его .
Запомните, когда вы передаете объект и возвращаете объект по значению --> вызывается конструктор копирования.