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

Учитывая следующий код:

#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));]

Но я не вызываю конструктора копии!

6
задан Karl von Moor 9 February 2011 в 19:39
поделиться

3 ответа

Вы никогда не вызываете конструктор копирования. Конструктор копирования всегда неявно вызывается компилятором. Поэтому вам нужно научиться распознавать ситуации, когда он может быть вызван.

Когда вы прикрепляете ссылку на константу к временному объекту

...
return filter(channel, SpecialFilter(123, 321));
...

, компилятор имеет право выполнить копию временного объекта и потребовать доступный конструктор копии ( даже если на самом деле он не будет вызван). Это то, что является причиной проблемы в вашем случае.

Другими словами, когда вы делаете какой-то тип не копируемым, вы также отказываетесь от возможности прикреплять ссылки на константы к временным объектам этого типа.

11
ответ дан 9 December 2019 в 20:44
поделиться

Во-первых, удалите частное производное от SpecialFilter - в этом нет необходимости, так как Filter уже не копируется. Вот почему я считаю такие решения, как boost :: non_copyable, плохой идеей - есть более простые способы сказать, что вам не нужны копии.

Во-вторых, хотя я не уверен, что это ваша проблема, C ++ говорит, что публичный конструктор копирования должен быть доступен компилятору при нескольких обстоятельствах, , даже если компилятор фактически не использует его .

1
ответ дан 9 December 2019 в 20:44
поделиться

Запомните, когда вы передаете объект и возвращаете объект по значению --> вызывается конструктор копирования.

0
ответ дан 9 December 2019 в 20:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: