Поиск места ссылки на удаленную функцию

#c #visual-c #c 11 #copy-constructor #deleted-functions

#c #visual-c #c 11 #копировать-конструктор #удаленные функции

Вопрос:

IDE — Visual Studio Express 2013 для рабочего стола

C 11

Проблема — у меня есть класс, который, по-видимому, копируется (с использованием конструктора копирования). Если я объявлю конструктор копирования следующим образом:

 MyClass(const MyClassamp;) = delete;
  

Он жалуется на ссылку на удаленную функцию. Я уже дважды просмотрел весь свой код и не могу найти, куда будет скопирован экземпляр класса.

Есть ли какой-либо способ найти, откуда берется ссылка?

Я пытался определить конструктор копирования с точкой останова в нем, но она никогда не попадала.

Обновить

Извините, это действительно показывает, где находится ссылка — в некотором распределителе в STL. Мне удалось отследить ее до вызова std::vector::emplace_back(), который должен вызвать копирование. Я изучу это.

Обновление 2

Я такой тупица — у меня был вектор MyClass…

Комментарии:

1. Это было бы ошибкой компилятора, и любой приличный компилятор точно сказал бы вам, где возникает ошибка.

2. Вы пытались очистить и перестроить проект?

3. Выполните поиск по MyClass x=y , MyClass x(y) и MyClass* x = new MyClass(y) .

4. Чтобы увеличить ваши шансы на получение значимого ответа (и избежать отрицательных отзывов), пожалуйста, отправьте sscce.org и скопируйте-вставьте все полученное сообщение об ошибке компилятора. Еще лучше, если вы включите все предупреждения, перекомпилируете, а затем скопируете и вставите все предупреждения.

5. О, также проверьте, отправляете ли вы в функцию или возвращаете из функции MyClass экземпляр по значению . Я полагаю, что конструктор копирования неявно вызывается в обоих случаях, чтобы реплицировать этот экземпляр в стеке.

Ответ №1:

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

http://connect.microsoft.com/VisualStudio/feedback/details/889420/issue-with-delete

В нем говорится, что IDE (IntelliSense) выдает жалобы, в то время как компилятор этого не делает, что объясняет, почему вы не опубликовали никакого сообщения об ошибке компилятора и почему вы на самом деле могли бы выполнить скомпилированную программу с точками останова в первую очередь.

Саму ошибку легко воспроизвести:

 struct Example
{
  Example() {}
  Example(Example const amp;) = delete;
};

Example f()
{
  return Example();
}

int main()
{
  Example e = f();
}
  

Скомпилирован с помощью VC 2013 следующим образом:

 cl /nologo /EHsc /W4 /Za stackoverflow.cpp
  

Нет ошибки, нет предупреждения.

Теперь, если вы перейдете к http://www.compileonline.com/compile_cpp11_online.php вместо этого скомпилируйте тот же код с помощью GCC 4.7.2, есть ожидаемые ошибки компилятора:

 main.cpp: In function ‘Example f()’:
main.cpp:9:18: error: use of deleted function ‘Example::Example(const Exampleamp;)’
   return Example();
                  ^
main.cpp:4:3: error: declared here
   Example(Example const amp;) = delete;
   ^
main.cpp: In function ‘int main()’:
main.cpp:14:17: error: use of deleted function ‘Example::Example(const Exampleamp;)’
   Example e = f();
                 ^
main.cpp:4:3: error: declared here
   Example(Example const amp;) = delete;
   ^
  

Итак, на самом деле у вас две проблемы:

  1. В вашем компиляторе обнаружена ошибка. Это может быть решено только путем обновления до более новой версии, если / когда она будет доступна.

  2. Ваш код вызывает конструктор копирования для класса, который не разрешает копирование.

Вторую проблему можно решить, рассмотрев правила, по которым C копирует объект «косвенно» — или требует присутствия конструктора копирования , даже если фактическое копирование оптимизировано. Проверьте код еще раз в поисках следующих случаев:

  • Передача по значению. void f(MyClass obj); .
  • Возврат по значению. MyClass f(); .
  • Выбрасывание. throw MyClass();

Первая ошибка легко исправляется:

void f(MyClass const amp;obj);

Остальные требуют более тщательной переработки, потому что возврат или выбрасывание напрямую противоречит идее предотвращения копий.

Комментарии:

1. Я думаю, проблема скорее в том, что где-то в моем коде выполняется явное или неявное копирование в MyClass. Я хочу удалить это, поскольку я хочу, чтобы MyClass был «не копируемым». Проблема заключается в поиске ссылки на удаленную функцию.

2. @Brett: Еще что вы имеете в виду, говоря, что где-то есть явная или неявная копия? Это именно то, что я объяснил во второй половине моего ответа, где я привел примеры неявных копий.