помилка: використання видаленої функції


121

Я працюю над кодом C ++, який написав друг, і я отримую таку помилку, яку я ніколи не бачив при компілюванні з gcc4.6:

error: use of deleted function

GameFSM_<std::array<C, 2ul> >::hdealt::hdealt()’ is implicitly deleted because the default definition would be ill-formed:
uninitialized non-static const member const h_t FlopPokerGameFSM_<std::array<C, 2ul> >::hdealt::h

Редагувати: Це походить від частини коду за допомогою boost MSM: Boost Webpage

Edit2: у вихідному коді = delete()ніде не використовується.

Взагалі кажучи, що ця помилка означає? Що я повинен шукати, коли виникає такий тип помилок?


4
і код, який ви збираєте?
ColWhi

Мені було просто цікаво, що означає помилка? Чи потрібно також розміщувати код для цього?
човник87

1
gcc.gnu.org/bugzilla/show_bug.cgi?id=47417 може допомогти, ви також використовуєте прискорення?
ColWhi

@Sasquiha, так, я використовую прискорений MSM.
човник87

20
Оскільки це з'являється як перша відповідність Google для подібного типу помилок - справа не в цьому, але найчастіша причина такої помилки - це після того, як ви додали в клас якийсь спеціальний конструктор - в результаті компілятор припиняє створювати конструктор за замовчуванням. , і якщо примірник класу коли-небудь створюється через конструктор за замовчуванням, з’являється ця помилка. Просто додайте конструктор за замовчуванням чітко.
СФ.

Відповіді:


170

Повідомлення про помилку чітко говорить про те, що конструктор за замовчуванням видалено неявно . Це навіть говорить чому: клас містить нестатичну змінну const, яка не була б ініціалізована ctor за замовчуванням.

class X {
    const int x;
};

Так як X::xце const, він повинен буде почати - але по замовчуванням не т е р зазвичай форматувати його (бо це тип POD). Тому, щоб отримати ctor за замовчуванням, потрібно визначити його самостійно (і він повинен ініціалізуватися x). Ви можете отримати таку ж ситуацію з членом, що є довідкою:

class X { 
    whatever &x;
};

Напевно, варто відзначити, що обидва вони також відключать неявне створення оператора присвоєння, по суті, з тієї ж причини. Оператор неявного присвоєння зазвичай виконує призначення членів, але з членом const або референтним членом він не може цього зробити, оскільки член не може бути призначений. Щоб виконати завдання, потрібно написати власного оператора присвоєння.

Ось чому constчлен, як правило, повинен стати статичним - коли ви робите завдання, ви не можете призначити члена const. У типовому випадку всі ваші екземпляри матимуть однакове значення, тому вони можуть також мати доступ до однієї змінної замість того, щоб мати багато копій змінної, які будуть мати однакове значення.

Звичайно, можна створити екземпляри з різними значеннями, хоча ви (наприклад) передаєте значення під час створення об'єкта, тому два різних об'єкти можуть мати два різних значення. Якщо ж ви спробуєте зробити щось подібне до їх заміни, член const збереже своє первісне значення замість того, щоб заміняти їх.


@Jeffry Coffin: Фактичне повідомлення про помилку було розміщено як редагування, початкове повідомлення про помилку було розміщено лишеC++ error: use of deleted function
Alok Save

1
@Als: Вибачте, я, мабуть, мав би бути явним, що я не мав намір це образа чи щось на тому розпорядженні, лише те, що було на сьогодні доступне, дало зрозуміти, що ці відповіді не були правильними.
Джеррі Труну

Ніяких проблем, я не хотів бути непохитним ... Ваша відповідь є фантастичною і найкраще пояснює ситуацію. +1 від мене :)
Alok Зберегти

Я припускаю , що ви могли б допомогти мені з моєю проблемою тут , будь ласка: stackoverflow.com/questions/23349524 / ...
Сахер ахваль

2
@OllieFord: Це залежить. Що має відбутися, якщо (наприклад) ви присвоїте об'єкт з одним значенням у цьому полі іншому, яке має інше значення у цьому полі? Якщо його слід перезаписати, то це не може бути const. Якщо це взагалі не повинно бути дозволено, то значення дійсно може бути частиною типу (наприклад, параметр шаблону, якщо він відомий під час компіляції).
Джеррі Труну

11

Ви використовуєте функцію, яка позначена як deleted.
Наприклад:

int doSomething( int ) = delete;

= Delete - це нова функція C ++ 0x. Це означає, що компілятор повинен негайно припинити компілювати та скаржитися на "цю функцію видалено", коли користувач використовує таку функцію.

Якщо ви бачите цю помилку, слід перевірити декларацію функції =delete.

Щоб дізнатися більше про цю нову функцію, представлену в C ++ 0x, перевірте це .


7
Коли з цікавості, коли щось подібне може бути корисним?
Пепе

@Peter: запобігання неявних конверсій.
Р. Мартиньо Фернандес

7
Насправді в ньому написано "неявно видалено, тому що ..." , наведений вище приклад був би явним.
Георг Фріцше

@ Peter R: схоже, це такий приклад: en.wikipedia.org/wiki/…
shuttle87

1
@Downvoter: Фактичне повідомлення про помилку було розміщено як редагування, лише початкове повідомлення про помилку було розміщеноC++ error: use of deleted function
Alok Зберегти

4

gcc 4.6 підтримує нову функцію видалених функцій, куди можна писати

hdealt() = delete;

щоб відключити конструктор за замовчуванням.

Тут компілятор, очевидно, бачив, що конструктор за замовчуванням не може бути сформований, і =deleteце буде для вас.


2

Я зіткнувся з цією помилкою при успадкуванні від абстрактного класу і не реалізувавши всі чисті віртуальні методи у своєму підкласі.


1
Так само я отримав те саме, виходячи public virtualз базового класу 2-го рівня, де базовий клас 1-го рівня мав явно видалений конструктор за замовчуванням. Видалення virtualвирішило проблему без необхідності впровадження всіх методів.
Мейтре Барт

1

У поточному стандарті C ++ 0x ви можете явно відключити конструктори за замовчуванням за допомогою синтаксису видалення, наприклад

MyClass() = delete;

Gcc 4.6 - це перша версія, яка підтримує цей синтаксис, тому, можливо, в цьому проблема ...


Gcc 4.6 is the first version to support this syntaxЯ думаю, це пояснило б, чому я ніколи цього не бачив, оскільки нещодавно я почав використовувати gcc4.6.
човник87

2
Я використовую цей синтаксис із GCC 4.5 протягом багатьох років. Я маю на увазі дні.
Р. Мартіньо Фернандес

Ах, мабуть, я мав на увазі делеговані диски, які містяться в GCC 4.6.
jarmond

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.