C error c2280

C++ Documentation. Contribute to MicrosoftDocs/cpp-docs development by creating an account on GitHub.
description title ms.date f1_keywords helpviewer_keywords ms.assetid

Learn more about: Compiler Error C2280

Compiler Error C2280

04/25/2017

C2280

C2280

e6c5b1fb-2b9b-4554-8ff9-775eeb37161b

Compiler Error C2280

declaration‘: attempting to reference a deleted function

The compiler detected an attempt to reference a deleted function. This error can be caused by a call to a member function that has been explicitly marked as = deleted in the source code. This error can also be caused by a call to an implicit special member function of a struct or class that is automatically declared and marked as deleted by the compiler. For more information about when the compiler automatically generates default or deleted special member functions, see Special member functions.

Example: Explicitly deleted functions

A call to an explicitly deleted function causes this error. An explicitly deleted member function implies that the class or struct is intentionally designed to prevent its use, so to fix this issue, you should change your code to avoid it.

// C2280_explicit.cpp
// compile with: cl /c /W4 C2280_explicit.cpp
struct A {
    A();
    A(int) = delete;
};

struct B {
    A a1;
    A a2 = A(3); // C2280, calls deleted A::A(int)
    // To fix, remove the call to A(int)
};

void f() {
    B b;    // calls implicit B::B(void)
}

Example: Uninitialized data members

An uninitialized reference type data member or const data member causes the compiler to implicitly declare a deleted default constructor. To fix this issue, initialize the data member when it is declared.

// C2280_uninit.cpp
// compile with: cl /c C2280_uninit.cpp
struct A {
    const int i; // uninitialized const-qualified data
    // members or reference type data members cause
    // the implicit default constructor to be deleted.
    // To fix, initialize the value in the declaration:
    // const int i = 42;
} a;    // C2280

Example: Reference and const data members

A const or reference type data member causes the compiler to declare a deleted copy assignment operator. Once initialized, these members can’t be assigned to, so a simple copy or move can’t work. To fix this issue, we recommend you change your logic to remove the assignment operations that cause the error.

// C2280_ref.cpp
// compile with: cl /c C2280_ref.cpp
extern int k;
struct A {
    A();
    int& ri = k; // a const or reference data member causes
    // implicit copy assignment operator to be deleted.
};

void f() {
    A a1, a2;
    // To fix, consider removing this assignment.
    a2 = a1;    // C2280
}

Example: Movable deletes implicit copy

If a class declares a move constructor or move assignment operator, but does not explicitly declare a copy constructor, the compiler implicitly declares a copy constructor and defines it as deleted. Similarly, if a class declares a move constructor or move assignment operator, but does not explicitly declare a copy assignment operator, the compiler implicitly declares a copy assignment operator and defines it as deleted. To fix this issue, you must explicitly declare these members.

When you see error C2280 in connection with a unique_ptr, it is almost certainly because you are attempting to invoke its copy constructor, which is a deleted function. By design, a unique_ptr cannot be copied. Use a move constructor to transfer ownership instead.

// C2280_move.cpp
// compile with: cl /c C2280_move.cpp
class base
{
public:
    base();
    ~base();
    base(base&&);
    // Move constructor causes copy constructor to be
    // implicitly declared as deleted. To fix this
    // issue, you can explicitly declare a copy constructor:
    // base(base&);
    // If you want the compiler default version, do this:
    // base(base&) = default;
};

void copy(base *p)
{
    base b{*p};  // C2280
}

Example: Variant and volatile members

Versions of the compiler before Visual Studio 2015 Update 2 were non-conforming and generated default constructors and destructors for anonymous unions. These are now implicitly declared as deleted. Those versions also allowed non-conforming implicit definition of default copy and move constructors and default copy and move assignment operators in classes and structs that have volatile member variables. The compiler now considers these to have non-trivial constructors and assignment operators, and doesn’t generate default implementations. When such a class is a member of a union, or an anonymous union inside of a class, the copy and move constructors and copy and move assignment operators of the union or class are implicitly defined as deleted. To fix this issue, you must explicitly declare the required special member functions.

// C2280_variant.cpp
// compile with: cl /c C2280_variant.cpp
struct A {
    A() = default;
    A(const A&);
};

struct B {
    union {
        A a;
        int i;
    };
    // To fix this issue, declare the required
    // special member functions:
    // B();
    // B(const B& b);
};

int main() {
    B b1;
    B b2(b1);  // C2280
}

Example: Indirect base members deleted

Versions of the compiler before Visual Studio 2015 Update 2 were non-conforming and allowed a derived class to call special member functions of indirectly-derived private virtual base classes. The compiler now issues compiler error C2280 when such a call is made.

In this example, class top indirectly derives from private virtual base. In conforming code, this makes the members of base inaccessible to top; an object of type top can’t be default constructed or destroyed. To fix this issue in code that relied on the old compiler behavior, change the intermediate class to use protected virtual derivation, or change the top class to use direct derivation:

// C2280_indirect.cpp
// compile with: cl /c C2280_indirect.cpp
class base
{
protected:
    base();
    ~base();
};

class middle : private virtual base {};
// Possible fix: Replace line above with:
// class middle : protected virtual base {};
class top : public virtual middle {};    // C4594, C4624
// Another possible fix: use direct derivation:
// class top : public virtual middle, private virtual base {};

void destroy(top *p)
{
    delete p;  // C2280
}

This snippet is compiled without errors in Visual Studio 2013 (Version 12.0.31101.00 Update 4)

class A
{
public:
   A(){}
   A(A &&){}
};

int main(int, char*)
{
   A a;
   new A(a);
   return 0;
}

while it is compiled with this error in Visual Studio 2015 RC (Version 14.0.22823.1 D14REL):

1>------ Build started: Project: foo, Configuration: Debug Win32 ------
1>  foo.cpp
1>c:devfoofoo.cpp(11): error C2280: 'A::A(const A &)': attempting to reference a deleted function
1>  c:devfoofoo.cpp(6): note: compiler has generated 'A::A' here
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

I think that the compiler shipped with Visual Studio 2015 generates the Copy Constructor and marks it as =delete and so I get the error C2280 (which, by the way, I cannot find documented on msdn.microsoft.com).

Now, let’s say I have a codebase which is compilable with Visual Studio 2013 (and it works because it relies on the code generated automatically by the compiler) but not compilable with Visual Studio 2015 due to C2280, how can I fix the problem?

I was thinking to declare class A in this way:

class A
{
public:
   A(){}
   A(A &&){}
   A(const A&)=default;
};

am I missing something?

asked Jul 7, 2015 at 9:37

Alessandro Jacopson's user avatar

2

From [class.copy]/7, emphasis mine:

If the class definition does not explicitly declare a copy constructor, a non-explicit one is declared implicitly.
If the class definition declares a move constructor or move assignment operator, the implicitly declared copy
constructor is defined as deleted
; otherwise, it is defined as defaulted (8.4). The latter case is deprecated if
the class has a user-declared copy assignment operator or a user-declared destructor.

There is an equivalent section with similar wording for copy assignment in paragraph 18. So your class is really:

class A
{
public:
   // explicit
   A(){}
   A(A &&){}

   // implicit
   A(const A&) = delete;
   A& operator=(const A&) = delete;
};

which is why you can’t copy-construct it. If you provide a move constructor/assignment, and you still want the class to be copyable, you will have to explicitly provide those special member functions:

    A(const A&) = default;
    A& operator=(const A&) = default;

You will also need to declare a move assignment operator. If you really have a need for these special functions, you will also probably need the destructor. See Rule of Five.

answered Jul 7, 2015 at 10:38

Barry's user avatar

I had the same problem and it was due to a poorly defined member variable:

double const deltaBase = .001;

Putting this in will cause the copy constructor to be deleted. Get rid of the «const» and assign in the constructor.

answered May 30, 2016 at 3:14

doby's user avatar

dobydoby

5254 silver badges9 bronze badges

3

I encountered the same error, just because I had misused std::unique_ptr.

Note that std::unique_ptr is non-copyable, it is only moveable.

Here is the wrong demonstration.

class word;
class sentence
{
    public:
        sentence();
        ~sentence();

    public:
        // Wrong demonstration, because I pass the parameter by value/copying
        // I should use 'std::shared_ptr< word >' instead.
        sentence(std::initializer_list< std::unique_ptr< word > > sentence);
};

The following code is taken from MSVC compiler’s STL library. We can see that the copy constructor and copy assignment operator of class unique_ptr are deleted explicitly.

    unique_ptr(const unique_ptr&) = delete;
    unique_ptr& operator=(const unique_ptr&) = delete;

answered Sep 27, 2020 at 15:43

QingJia Wang's user avatar

2

I was stuck with this error even after «default»ing the copy ctor. Turned out, one of my class member (rapidjson’s Document object) was disallowing copy. Changed it to a reference, initialized via a *(new rapidjson::Document()) in the default ctor’s initializer list. Looks like all individual members should also be copy’able in addition to the defaulted copy ctor.

answered Aug 19, 2019 at 13:00

Neelabh Mam's user avatar

Neelabh MamNeelabh Mam

3006 silver badges10 bronze badges

If you write a user-defined move constructor for your class, the copy constructor will be deleted. This is because if a class needs special behaviour for its move constructor, it probably needs some similar behaviour in its copy constructor, so the copy constructor will be deleted to stop you from inadvertently using the default behaviour.

If you want to define your own move constructor and use the default copy constructor, you need to declare it as default, like you suggested in your question:

class A
{
public:
   A(){}
   A(A &&){}
   //I know what I'm doing, compiler, use the default version.
   A(const A&)=default;
};

Note that if you define a custom move constructor, you should think about your assignment operators and destructor as well.

answered Jul 7, 2015 at 9:44

TartanLlama's user avatar

TartanLlamaTartanLlama

62.3k13 gold badges154 silver badges190 bronze badges

1

I ran into a similar situation where I had a hierarchy of classes and a destructor in the base class was declared virtual. In this case, compiler does NOT automatically generate move and copy constructors. So we have to default these in order for compiler to generate the definitions for these methods.

However, I ran into another issue after I defaulted copy and move constructor. I saw that the compiler was still not able to generate copy and move constructors. The reason was the usage of std::atomic member variable in the base class. Since atomic variable are not copy able or movable, the compiler could not generate definitions for copy constructor. This gave me lot of headache and I had to solve the problem using a different method.
See other great answers for similar issue that I faced.

References:
Does a default virtual destructor prevent compiler-generated move operations?

Error with copy constructor/assignment operator for a class which has std::atomic member variable

answered Oct 31, 2019 at 23:35

piyu2cool's user avatar

I faced this issue today and mine was caused by having both std::stringstream and std::ostream as member variables. I initially thought this was caused because I accidentally named one of them as sstream which was the name for the header file <sstreamn> I had included previously.

But changing the name didn’t help, and I had to remove the ostream variable completely for this to work again! then I realized I had declared it incorrectly like this:

std::ostream some_stream;

while it should have been :

...
std::ostream some_stream(&filebuf);

Basically, I was much better off using ofstream instead!

answered Oct 3, 2020 at 12:52

Hossein's user avatar

HosseinHossein

23.3k34 gold badges117 silver badges217 bronze badges

0

Содержание

  1. Ошибка компилятора C2280
  2. Пример. Явно удаленные функции
  3. Пример. Неинициализированные элементы данных
  4. Пример. Элементы данных reference и const
  5. Пример. Перемещаемый удаляет неявную копию
  6. Пример: переменные и переменные члены
  7. Пример. Удаление непрямых базовых элементов
  8. Compiler Error C2280
  9. Example: Explicitly deleted functions
  10. Example: Uninitialized data members
  11. Example: Reference and const data members
  12. Example: Movable deletes implicit copy
  13. Example: Variant and volatile members
  14. Example: Indirect base members deleted
  15. Name already in use
  16. cpp-docs / docs / error-messages / compiler-errors-1 / compiler-error-c2280.md
  17. Изменения в Visual C++
  18. Изменения в компиляторе
  19. Изменения в C Runtime Library (CRT)
  20. Общие изменения

Ошибка компилятора C2280

«declaration«: попытка ссылки на удаленную функцию

Компилятор обнаружил попытку сослаться на функцию deleted . Эта ошибка может быть вызвана вызовом функции-члена, которая была явно помечена как = deleted в исходном коде. Эта ошибка также может быть вызвана вызовом неявной специальной функции-члена структуры или класса, которая автоматически объявляется и помечается компилятором как deleted . Дополнительные сведения о том, когда компилятор автоматически создает специальные deleted функции-члены, см. в разделе Специальные функции-члены default .

Пример. Явно удаленные функции

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

Пример. Неинициализированные элементы данных

Неинициализированный элемент данных ссылочного типа или const член данных приводит к тому, что компилятор неявно объявляет deleted конструктор по умолчанию. Чтобы устранить эту проблему, инициализируйте элемент данных при его объявлении.

Пример. Элементы данных reference и const

Элемент const данных ссылочного типа или вызывает объявление компилятором deleted оператора присваивания копирования. После инициализации эти члены не могут быть назначены, поэтому простая копия или перемещение не могут работать. Чтобы устранить эту проблему, рекомендуется изменить логику, чтобы удалить операции назначения, которые вызывают ошибку.

Пример. Перемещаемый удаляет неявную копию

Если класс объявляет конструктор перемещения или оператор присваивания перемещения, но явно не объявляет конструктор копирования, компилятор неявно объявляет конструктор копирования и определяет его как deleted . Аналогичным образом, если класс объявляет конструктор перемещения или оператор присваивания перемещения, но явно не объявляет оператор присваивания копирования, компилятор неявно объявляет оператор присваивания копирования и определяет его как deleted . Чтобы устранить эту проблему, необходимо явно объявить эти члены.

Если вы видите ошибку C2280 в связи с , это почти наверняка связано с unique_ptr тем, что вы пытаетесь вызвать его конструктор копирования, который является функцией deleted . По умолчанию невозможно скопировать unique_ptr объект . Вместо этого используйте конструктор перемещения для передачи прав владения.

Пример: переменные и переменные члены

Версии компилятора до Visual Studio 2015 с обновлением 2 были несоответствующими и создали конструкторы и деструкторы по умолчанию для анонимных объединений. Теперь они неявно объявлены как deleted . Эти версии также допускали несоответствующее неявное определение default конструкторов копирования и перемещения, default а также операторов присваивания копирования и перемещения в классах и конструкциях, имеющих volatile переменные-члены. Компилятор теперь считает их нетривиальными конструкторами и операторами присваивания и не создает default реализации. Если такой класс является членом объединения или анонимным объединением внутри класса, конструкторы копирования и перемещения и операторы присваивания копирования и перемещения объединения или класса неявно определяются как deleted . Чтобы устранить эту проблему, необходимо явно объявить необходимые специальные функции-члены.

Пример. Удаление непрямых базовых элементов

Версии компилятора до Visual Studio 2015 с обновлением 2 были несоответствующими и позволяли производному классу вызывать специальные функции-члены private virtual косвенных базовых классов. Компилятор теперь выдает ошибку C2280 при таком вызове.

В этом примере класс top косвенно является производным от частного виртуального base . В соответствующем коде это делает элементы base недоступными для top ; объект типа top не может быть создан или уничтожен по умолчанию. Чтобы устранить эту проблему в коде, который использовал старое поведение компилятора, измените промежуточный класс на использование protected virtual наследования или измените top класс на использование прямого наследования:

Источник

Compiler Error C2280

declaration‘: attempting to reference a deleted function

The compiler detected an attempt to reference a deleted function. This error can be caused by a call to a member function that has been explicitly marked as = deleted in the source code. This error can also be caused by a call to an implicit special member function of a struct or class that is automatically declared and marked as deleted by the compiler. For more information about when the compiler automatically generates default or deleted special member functions, see Special member functions.

Example: Explicitly deleted functions

A call to an explicitly deleted function causes this error. An explicitly deleted member function implies that the class or struct is intentionally designed to prevent its use, so to fix this issue, you should change your code to avoid it.

Example: Uninitialized data members

An uninitialized reference type data member or const data member causes the compiler to implicitly declare a deleted default constructor. To fix this issue, initialize the data member when it is declared.

Example: Reference and const data members

A const or reference type data member causes the compiler to declare a deleted copy assignment operator. Once initialized, these members can’t be assigned to, so a simple copy or move can’t work. To fix this issue, we recommend you change your logic to remove the assignment operations that cause the error.

Example: Movable deletes implicit copy

If a class declares a move constructor or move assignment operator, but does not explicitly declare a copy constructor, the compiler implicitly declares a copy constructor and defines it as deleted . Similarly, if a class declares a move constructor or move assignment operator, but does not explicitly declare a copy assignment operator, the compiler implicitly declares a copy assignment operator and defines it as deleted . To fix this issue, you must explicitly declare these members.

When you see error C2280 in connection with a unique_ptr , it is almost certainly because you are attempting to invoke its copy constructor, which is a deleted function. By design, a unique_ptr cannot be copied. Use a move constructor to transfer ownership instead.

Example: Variant and volatile members

Versions of the compiler before Visual Studio 2015 Update 2 were non-conforming and generated default constructors and destructors for anonymous unions. These are now implicitly declared as deleted . Those versions also allowed non-conforming implicit definition of default copy and move constructors and default copy and move assignment operators in classes and structs that have volatile member variables. The compiler now considers these to have non-trivial constructors and assignment operators, and doesn’t generate default implementations. When such a class is a member of a union, or an anonymous union inside of a class, the copy and move constructors and copy and move assignment operators of the union or class are implicitly defined as deleted . To fix this issue, you must explicitly declare the required special member functions.

Example: Indirect base members deleted

Versions of the compiler before Visual Studio 2015 Update 2 were non-conforming and allowed a derived class to call special member functions of indirectly-derived private virtual base classes. The compiler now issues compiler error C2280 when such a call is made.

In this example, class top indirectly derives from private virtual base . In conforming code, this makes the members of base inaccessible to top ; an object of type top can’t be default constructed or destroyed. To fix this issue in code that relied on the old compiler behavior, change the intermediate class to use protected virtual derivation, or change the top class to use direct derivation:

Источник

Name already in use

cpp-docs / docs / error-messages / compiler-errors-1 / compiler-error-c2280.md

  • Go to file T
  • Go to line L
  • Copy path
  • Copy permalink

Copy raw contents

Copy raw contents

Compiler Error C2280

declaration‘: attempting to reference a deleted function

The compiler detected an attempt to reference a deleted function. This error can be caused by a call to a member function that has been explicitly marked as = deleted in the source code. This error can also be caused by a call to an implicit special member function of a struct or class that is automatically declared and marked as deleted by the compiler. For more information about when the compiler automatically generates default or deleted special member functions, see Special member functions.

Example: Explicitly deleted functions

A call to an explicitly deleted function causes this error. An explicitly deleted member function implies that the class or struct is intentionally designed to prevent its use, so to fix this issue, you should change your code to avoid it.

Example: Uninitialized data members

An uninitialized reference type data member or const data member causes the compiler to implicitly declare a deleted default constructor. To fix this issue, initialize the data member when it is declared.

Example: Reference and const data members

A const or reference type data member causes the compiler to declare a deleted copy assignment operator. Once initialized, these members can’t be assigned to, so a simple copy or move can’t work. To fix this issue, we recommend you change your logic to remove the assignment operations that cause the error.

Example: Movable deletes implicit copy

If a class declares a move constructor or move assignment operator, but does not explicitly declare a copy constructor, the compiler implicitly declares a copy constructor and defines it as deleted . Similarly, if a class declares a move constructor or move assignment operator, but does not explicitly declare a copy assignment operator, the compiler implicitly declares a copy assignment operator and defines it as deleted . To fix this issue, you must explicitly declare these members.

When you see error C2280 in connection with a unique_ptr , it is almost certainly because you are attempting to invoke its copy constructor, which is a deleted function. By design, a unique_ptr cannot be copied. Use a move constructor to transfer ownership instead.

Example: Variant and volatile members

Versions of the compiler before Visual Studio 2015 Update 2 were non-conforming and generated default constructors and destructors for anonymous unions. These are now implicitly declared as deleted . Those versions also allowed non-conforming implicit definition of default copy and move constructors and default copy and move assignment operators in classes and structs that have volatile member variables. The compiler now considers these to have non-trivial constructors and assignment operators, and doesn’t generate default implementations. When such a class is a member of a union, or an anonymous union inside of a class, the copy and move constructors and copy and move assignment operators of the union or class are implicitly defined as deleted . To fix this issue, you must explicitly declare the required special member functions.

Example: Indirect base members deleted

Versions of the compiler before Visual Studio 2015 Update 2 were non-conforming and allowed a derived class to call special member functions of indirectly-derived private virtual base classes. The compiler now issues compiler error C2280 when such a call is made.

In this example, class top indirectly derives from private virtual base . In conforming code, this makes the members of base inaccessible to top ; an object of type top can’t be default constructed or destroyed. To fix this issue in code that relied on the old compiler behavior, change the intermediate class to use protected virtual derivation, or change the top class to use direct derivation:

Источник

Изменения в Visual C++

Когда вы захотите обновить версию Visual C++ компилятора (например, перейти с Visual Studio с 2013 на 2015), будет не лишним узнать, почему вы можете столкнуться с тем, что код, который прежде успешно компилировался и выполнялся, теперь будет вызывать ошибки компиляции и/или ошибки времени выполнения.
Эти проблемы могут быть вызваны многочисленными изменениями компилятора для соответствия стандарту С++, изменениями в сигнатурах функций или изменениями расположения объектов в памяти.

Для того, чтобы избежать ошибок времени выполнения (их, как известно, наиболее трудно найти), мы рекомендуем никогда не делать статическое связывание с двоичными файлами, полученными другой версией компилятора. Также при обновлении своей программы (EXE или DLL), убедитесь, что используемые библиотеки тоже собраны новой версией компилятора.
Если вы используете типы из CRT (C Runtime) или STL (Standard Template Library), не передавайте их между двоичными файлами (включая DLL), которые собраны разными версиями компилятора. Более подробно этот вопрос рассмотрен в Potential Errors Passing CRT Objects Across DLL Boundaries.
И в дальнейшем мы рекомендуем не писать код, который зависит от конкретного расположения объектов в памяти (если это не COM интерфейс или POD объект). Если у вас сейчас есть такой код, после обновления компилятора вам следует убедиться, что все работает как надо. Более подробно можно почитать здесь: Portability At ABI Boundaries (Modern C++).

Ниже в статье описываются изменения в компиляторе Visual C++ (который идет с Visual Studio 2015 Preview). В статье слова «новое поведение» и «сейчас» относятся именно к этой версии, а «старое поведение» и «раньше» — к Visual Studio 2013 (и более ранним версиям).

Краткое содержание:
— Изменения в компиляторе
— Изменения в C Runtime Library (CRT)
— Изменения в STL
— Изменения в MFC и ATL

Изменения в компиляторе

    /Zc:forScope — Флаг компилятора /Zc:forScope- объявлен устаревшим (deprecated) и в будущем будет удален. Сейчас компилятор при использовании этого флага будет выкидывать предупреждение D9035.
    Данный флаг используется для использования нестандартного расширения С++ — использование переменных, объявленных в описании цикла for за пределами этого цикла. Этот флаг необходим только если установлен другой флаг — /Za (соответствовать стандарту), потому что без /Za , использование переменных из описания цикла по умолчанию разрешено. Если вам не нужно заботиться о кроссплатформенности (например, не предполагается собирать код другими компиляторами), вы можете выключить флаг /Za (установить свойству проекта «Disable Language Extensions» значение «No»). Если же вы заботитесь о кроссплатформенности и соответствия стандарту, значит такие участки кода нужно переписать, переместив объявление переменной выше цикла:

/Zg
Флаг компилятора /Zg (создание прототипов функций) больше недоступен для использования (раньше у него был атрибут deprecated)

Теперь нельзя запустить юнит-тесты, использующие C++/CLI, из командной строки используя mstest.exe, взамен нужно использовать vtest.console.exe. Более подробно можно узнать об этом здесь: VSTest.Console.exe command-line options.

Ключевое слово mutable
Теперь использование mutable , в соответствии со стандартом, допускается только применимо к именам членов класса, и не может быть применено к ссылкам, или именам, объявленным как const или static . Пример:

Раньше это компилировалось, теперь компилятор выдаст ошибку С2071. Для исправления, нужно просто убрать mutable .

char_16_t и char_32_t
Теперь нельзя использовать char_16_t и char_32_t в качестве псевдонимов пользовательских типов, потому что сейчас эти типы определяются как встроенные. Раньше было довольно распространенной практикой для авторов библиотек определять char_16_t и char_32_t в качестве псевдонимов для uint_16_t и uint_32_t, соответственно.

Для исправления нужно убрать объявление псевдонимов и переименовать любые другие идентификаторы конфликтующие со вновь введенными.

Нетиповые (non-type) параметры шаблонов
Код, включающий в себя нетиповые параметры шаблонов сейчас правильно проверяется на совместимость типов. Например, следующий код раньше компилировался без ошибок:

Сейчас компилятор выдаст ошибку, так как тип параметра шаблона не соответствует типу переданного аргумента (тип параметра — указатель на константный метод, но f не является константной).
error C2893: Failed to specialize function template ‘void S2::f(void)’
note: With the following template arguments:
note: ‘C=S1’
note: ‘Function=S1::f’

Для избавления от этой ошибки убедитесь, что тип аргумента шаблона полностью соотвествует типу параметра.

__declspec(align)
Компилятор больше не принимает __declspec(align) для функций. По правде говоря, он никогда и не принимал, но сейчас он будет выдавать ошибку С3323. Для избавления от нее просто уберите это выражение из объявления функции. Так как это и раньше не имело никакого эффекта, это не поменяет ничего в вашей программе.

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

Проблема здесь в том, что конструктор копирования объявлен приватным, таким образом, объект не может быть скопирован, что обычно требуется при обработке исключения. То же самое применимо в случае, когда конструктор объявлен explicit .

Для избавления от этой проблемы убедитесь, что конструктор для объекта исключения объявлен в публичной зоне и explicit .
При ловле исключения также требуется, чтобы объект был копируемым. Следующий код скомпилируется в ранних версиях Visual Studio, но сейчас будет ошибка:

Эту ошибку можно исправить, приняв исключение по ссылке:

Строки и макросы
Сейчас компилятор поддерживает определенные пользователем литералы (user defined literals — UDL). Как следствие этого, строки (точнее строковые литералы), за которыми без пробела поставлен макрос, интерпретируются как UDL, что может явиться причиной ошибки или неожиданного результата. Например, раньше это компилировалось без проблем:

Компилятор интрепретировал возвращаемое функцией func значение как строку «hello», и макрос, который раскрывался в «there», а затем соединял два этих литерала в один. Сейчас компилятор интерпретирует это как UDL, но так как не может найти определение _х среди известных ему UDL, он выдает ошибку:
error C3688: invalid literal suffix ‘_x’; literal operator or literal operator template ‘operator «»_x’ not found
note: Did you forget a space between the string literal and the prefix of the following string literal?
Для решения этой проблемы нужно поставить пробел между строкой и макросом.

Строки, расположенные рядом
Так же, как и в предыдущем случае, из-за изменений в разборе строк, строящие рядом строковые литералы, которые не разделяет пробел, раньше интерпретировались как одна строка, а сейчас для корректной компиляции нужно добавить пробел:

Просто добавьте пробел между строками:

Размещающий new и delete
Для соответствия стандарту С++14 было изменено поведение оператора delete . Детали можно прочитать в C++ Sized Deallocation. Была добавлена форма глобального оператора delete , которая принимает размер объекта. Важность этого изменения в том, что если в вашем коде есть оператор delete с такой же сигнатурой (соответствующая размещающему оператору new ), вы получите ошибку компиляции (С2956, которая указывает на строку с использованием оператора new , так как именно в этом месте компилятор пытается определить подходящий оператор delete ).
Функция void operator delete(void*, size_t) была размещающим оператором delete , соответствующим функции размещающего оператора new — void* operator new(size_t, size_t) из С++11. В новом стандарте С++14 этот delete стал обычной функцией деаллокации (то есть глобальным оператором delete ). Стандарт требует следующего — если размещающий new ищет соответствующий delete и находит стандартную функцию, программа не скомпилируется.
Например, предположим, ваш код определяет размещающий new и delete :

Проблема здесь в следующем: совпадение описания оператора размещающего delete и описания нового глобального оператора. Для того, чтобы избежать такого совпадения, можно использовать тип, отличный от size_t, при описании размера в размещающих операторах new и delete . Здесь нужно принять во внимание, что size_t зависит от компилятора, в Visual C++ это псевдоним для unsigned int. Хорошим решением здесь будет использование перечисления:

Затем, нужно изменить объявления размещающих операторов new и delete так, чтобы вторым параметром вместо size_t они принимали my_type. Также нужно будет подправить передачу аргумента в вызов new (например, с использованием static_cast совершить преобразование из целочисленного значения в перечисление) и изменить определение размещающих операторов, совершив преобразования из перечисления в целочисленный тип. Кроме перечисления можно использовать, например, класс, у которого будет поле типа size_t.
В качестве альтернативного решения можно убрать размещающий new . Если ваш код использует размещающий new для реализации пула и передаваемый размер — это размер объекта для размещения или удаления, в этом случае новый оператор delete может вполне подойти для удаления этого пула.
Если вы не хотите изменять поведение данных операторов в своем коде прямо сейчас, вы можете пока использовать флаг /Zc:sizedDealloc-, который вернет старое поведение. То есть не будет создано двух-аргументной функции удаления, и, таким образом, не будет никакого конфликта с определенной вами функцией удаления.

Поля объединений (union data members)
Теперь ссылки не могут быть полем объединения (union). Раньше этот код компилировался, теперь — нет:

Теперь возникают следующие ошибки:
test.cpp(67): error C2625: ‘U2::i’: illegal union member; type ‘int &’ is reference type

test.cpp(70): error C2625: ‘U3::i’: illegal union member; type ‘int &’ is reference type

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

Безымянные объединения (anonymous unions)
Безымянные объединения стали больше соответствовать стандарту. Раньше для безымянных объединений генерировался явный конструктор и деструктор. Сейчас они объявляются удаленными.

В Visual Studio 2015 Preview генерируются следующие ошибки:
error C2280: ‘ :: (void)’: attempting to reference a deleted function

note: compiler has generated ‘ :: ‘ here

Для решения этой проблемы, нужно определить свой конструктор и/или деструктор

Объединения с анонимными структурами
Для того, чтобы обеспечить соответствие стандарту, было изменено поведение времени выполнения для членов анонимных структур в объединениях. Конструктор анонимных структур — членов объединений — больше не вызывается неявно при создании объединения. Также деструктор таких полей не вызывается неявно при выходе объединения из блока видимости. Пример:

Раньше вызывался и конструктор и деструктор. Сейчас они не вызываются. Компилятор выдает предупреждения:
warning C4587: ‘U::s’: behavior change: constructor is no longer implicitly called

warning C4588: ‘U::s’: behavior change: destructor is no longer implicitly called

Для восстановления старого поведения нужно дать имя анонимной структуре. Поведение времени выполнения неанонимных структур остается независимой от версии компилятора.

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

Разрешение шаблонов (template resolution)
В разрешение имен для шаблонов также были внесены изменения. В С++, при рассмотрении кандидатов при разрешении имен, вполне возможен случай, когда одно или более имен могут быть неверными конкретизациями (invalid instantiation) шаблона. Эти неверные реализации обычно не вызывают ошибок компиляции (т.к. используется принцип, известный как SFINAE).

Сейчас, если SFINAE требует от компилятора конкретизировать шаблон класса, любые ошибки во время выполнения этой конкретизации будут считаться ошибками компилятора. Раньше эти ошибки игнорировались. Например:

Новый компилятор выдаст следующее сообщение об ошибке:
type_traits(1110): error C2139: ‘D’: an undefined class is not allowed as an argument to compiler intrinsic type trait ‘__is_base_of’

..t331.cpp(14): note: see declaration of ‘D’

..t331.cpp(10): note: see reference to class template instantiation ‘std::is_base_of ‘ being compiled

Причина ошибки в том, что в месте первого вызова is_base_of класс D еще не определен.
В этом случае исправление ошибки будет следующим: не нужно использовать такие проверки типов до определения классов, значит нужно перенести определение B и D d в начало файла. Если эти определения в заголовочных файлах, нужно проверить порядок включения, чтобы убедиться, что определения классов включаются раньше, чем используется проблемный шаблон.

  • Конструкторы копирования
    И в Visual Studio 2013 и в Visual Studio 2015 RC, компилятор создает конструктор копирования для класса, если в этом классе есть определенный пользователем конструктор перемещения, но нет определенного пользователем конструктора копирования. В Dev14 этот неявно генерируемый конструктор копирования помечается как «=delete».
  • Изменения в C Runtime Library (CRT)

    Общие изменения

      С++ перегрузка библиотечных функций
      Раньше в перегружались некоторые, но не все, математические библиотечные функции. В была определена перегрузка остальных функций. Это вело к проблемам разрешения перегрузки, если включен только . Теперь все перегрузки перенесены из в .

    Приведение в соответствие стандарту чисел с плавающей точкой
    В математической библиотеке было сделано много изменений для приближения к соответствию стандарту IEEE-754 и Приложению F стандарта C11, основное внимание было уделено особым случаям (NaN и бесконечности). Например, при передаче в функцию библиотеки NaN раньше часто возникала ошибка, сейчас — не возникает. Более подробно узнать об этом можно здесь: IEEE 754 Standard, Annex F of the C11 Standard.
    Эти изменения не вызовут ошибок времени компиляции, однако программа может начать вести себя по другому — более соответственно стандартам.

    FLT_ROUNDS
    Раньше этот макрос разворачивался в константное выражение, что было неправильно, так как способ округления числа мог измениться во время выполнения программы (например, с помощью fesetround). Сейчас FLT_ROUNDS это учитывает.

    Источник

    • Remove From My Forums
    • Question

    • I have a struct declaration as below:

      typedef struct Inner
      {    
          int nNum1;
          int nNum2;
          std::vector<wstring>v;
          
      }INNER, *PINNER;
       struct MyStruct  
      {
          enum
          {
              One,
              Two,
              Three
          }type;
          union
          {
          INNER inner;
          std::vector<MyStruct> Vec;
          }u;
      };
       std::vector<MyStruct> m_MyVector;

      I am aware that if a member of a structure is the same struct type we can have only a pointer to it. So the above declaration will give the error:

      Error C2280 ‘void *MyStruct::__delDtor(unsigned int)’: attempting to reference a deleted function

      What does this error actually mean? What about this ‘deleted function’?

      The error can be corrected with the below declaration

      typedef struct Inner
      {    
          int nNum1;
          int nNum2;
          std::vector<wstring>v;
          
      }INNER, *PINNER;
      
       struct MyStruct  
      {
          enum
          {
              One,
              Two,
              Three
          }type;
          union
          {
          INNER inner;
          std::vector<MyStruct*>* Vec;
          }u;
      };
      
       std::vector<MyStruct>* m_MyVector;

      Is the second declaration correct and acceptable? If it is correct, will the declaration of m_MyVector pointer demand creation of dynamic memory allocation to hold each MyStruct type in the vector? Can I accomplish the same without going for a pointer? Can
      someone please tell an outline of how I can use this struct in my code?

      • Edited by

        Thursday, December 17, 2015 7:08 PM

    Answers

    • On 12/17/2015 2:03 PM, its_me_here wrote:

      I have a struct declaration as below:

      typedef struct Inner
      {
               int nNum1;
               int nNum2;
               std::vector<wstring>v;
      
      }INNER, *PINNER;
          struct MyStruct
      {
               enum
               {
                       One,
                       Two,
                       Three
               }type;
               union
               {
               INNER inner;
               std::vector<MyStruct> Vec;
               }u;
      };
          std::vector<MyStruct> m_MyVector;

      I am aware that if a member of a structure is the same struct type we can have only a pointer to it. So the above declaration will give the error:

      Error C2280 ‘void *MyStruct::__delDtor(unsigned int)’: attempting to reference a deleted function

      The problem is not that you have vector<MyStruct> inside MyStruct. The problem is that you have a union whose member has a non-trivial destructor. The compiler cannot generate a destructor for MyStruct, because it has no way to know which member of
      the union is currently active — whether it should destroy u.inner or u.Vec. This is what the error message is telling you.

      What does this error actually mean? What about this ‘deleted function’?
      The error can be corrected with the below declaration

      typedef struct Inner
      {
               int nNum1;
               int nNum2;
               std::vector<wstring>v;
      
      }INNER, *PINNER;
      
          struct MyStruct
      {
               enum
               {
                       One,
                       Two,
                       Three
               }type;
               union
               {
               INNER inner;
               std::vector<MyStruct*>* Vec;
               }u;
      };
      
          std::vector<MyStruct>* m_MyVector;

      Here you’ve carefully avoided actually creating any instances of MyStruct, so the compiler doesn’t need to generate a destructor just yet. As soon as you attempt to create such an instance, you’ll have the error again.

      Is the second declaration correct and acceptable?

      Well, it would compile, but it’s pretty useless without the ability to actually create std::vector<MyStruct> that m_MyVector may point to, or to add any elements to it.

      Can someone please tell an outline of how I can use this struct in my code?

      Something along these lines:
      http://rextester.com/BXJO59203 (of course, you would destroy the appropriate member, not just the first one; I assume you somehow keep track of which one is valid at any given time).

      Or, save yourself some trouble and get rid of the union.

      • Proposed as answer by
        May Wang — MSFT
        Monday, December 21, 2015 4:46 AM
      • Marked as answer by
        May Wang — MSFT
        Tuesday, December 29, 2015 2:52 AM

    score:67

    Accepted answer

    From [class.copy]/7, emphasis mine:

    If the class definition does not explicitly declare a copy constructor, a non-explicit one is declared implicitly.
    If the class definition declares a move constructor or move assignment operator, the implicitly declared copy
    constructor is defined as deleted
    ; otherwise, it is defined as defaulted (8.4). The latter case is deprecated if
    the class has a user-declared copy assignment operator or a user-declared destructor.

    There is an equivalent section with similar wording for copy assignment in paragraph 18. So your class is really:

    class A
    {
    public:
       // explicit
       A(){}
       A(A &&){}
    
       // implicit
       A(const A&) = delete;
       A& operator=(const A&) = delete;
    };
    

    which is why you can’t copy-construct it. If you provide a move constructor/assignment, and you still want the class to be copyable, you will have to explicitly provide those special member functions:

        A(const A&) = default;
        A& operator=(const A&) = default;
    

    You will also need to declare a move assignment operator. If you really have a need for these special functions, you will also probably need the destructor. See Rule of Five.

    score:0

    I faced this issue today and mine was caused by having both std::stringstream and std::ostream as member variables. I initially thought this was caused because I accidentally named one of them as sstream which was the name for the header file <sstreamn> I had included previously.

    But changing the name didn’t help, and I had to remove the ostream variable completely for this to work again! then I realized I had declared it incorrectly like this:

    std::ostream some_stream;
    

    while it should have been :

    ...
    std::ostream some_stream(&filebuf);
    

    Basically, I was much better off using ofstream instead!

    score:3

    I encountered the same error, just because I had misused std::unique_ptr.

    Note that std::unique_ptr is non-copyable, it is only moveable.

    Here is the wrong demonstration.

    class word;
    class sentence
    {
        public:
            sentence();
            ~sentence();
    
        public:
            // Wrong demonstration, because I pass the parameter by value/copying
            // I should use 'std::shared_ptr< word >' instead.
            sentence(std::initializer_list< std::unique_ptr< word > > sentence);
    };
    

    The following code is taken from MSVC compiler’s STL library. We can see that the copy constructor and copy assignment operator of class unique_ptr are deleted explicitly.

        unique_ptr(const unique_ptr&) = delete;
        unique_ptr& operator=(const unique_ptr&) = delete;
    

    score:4

    If you write a user-defined move constructor for your class, the copy constructor will be deleted. This is because if a class needs special behaviour for its move constructor, it probably needs some similar behaviour in its copy constructor, so the copy constructor will be deleted to stop you from inadvertently using the default behaviour.

    If you want to define your own move constructor and use the default copy constructor, you need to declare it as default, like you suggested in your question:

    class A
    {
    public:
       A(){}
       A(A &&){}
       //I know what I'm doing, compiler, use the default version.
       A(const A&)=default;
    };
    

    Note that if you define a custom move constructor, you should think about your assignment operators and destructor as well.

    score:4

    I ran into a similar situation where I had a hierarchy of classes and a destructor in the base class was declared virtual. In this case, compiler does NOT automatically generate move and copy constructors. So we have to default these in order for compiler to generate the definitions for these methods.

    However, I ran into another issue after I defaulted copy and move constructor. I saw that the compiler was still not able to generate copy and move constructors. The reason was the usage of std::atomic member variable in the base class. Since atomic variable are not copy able or movable, the compiler could not generate definitions for copy constructor. This gave me lot of headache and I had to solve the problem using a different method.
    See other great answers for similar issue that I faced.

    References:
    Does a default virtual destructor prevent compiler-generated move operations?

    Error with copy constructor/assignment operator for a class which has std::atomic member variable

    score:5

    I was stuck with this error even after «default»ing the copy ctor. Turned out, one of my class member (rapidjson’s Document object) was disallowing copy. Changed it to a reference, initialized via a *(new rapidjson::Document()) in the default ctor’s initializer list. Looks like all individual members should also be copy’able in addition to the defaulted copy ctor.

    score:36

    I had the same problem and it was due to a poorly defined member variable:

    double const deltaBase = .001;
    

    Putting this in will cause the copy constructor to be deleted. Get rid of the «const» and assign in the constructor.

    Related Query

    • Visual studio 2015. c++ compiler error C2280 attempting to reference a deleted function
    • C++ Compiler Error C2280 «attempting to reference a deleted function» in Visual Studio 2013 and 2015
    • Compiler error C2280, attempting to reference a deleted function operator=
    • Error C2280: ‘std::thread::thread(const std::thread &)’ : attempting to reference a deleted function
    • error C2280: attempting to reference a deleted function
    • error C2280: attempting to reference a deleted function (atomic<int>)
    • error C2280: attempting to reference a deleted function while declaring a C++ struct
    • error C2280: attempting to reference a deleted function (trying to call vector.erase)
    • attempting to reference a deleted function
    • std::unique_ptr attempting to reference a deleted function
    • Attempting to reference a deleted function when using a mutex
    • C2280: attempting to reference a deleted function (union, struct, copy constructor)
    • ofstream in class — attempting to reference a deleted function
    • C++ copy constructor: attempting to reference a deleted function
    • attempting to reference a deleted function when passing by reference with a const member
    • ifstream attempting reference to a deleted function
    • unique_ptr with standard containers: attempting to reference a deleted function
    • Attempting to reference a deleted function using *this
    • std::thread::thread attempting to reference a deleted function
    • unorderered set for boost::asio::ip::tcp::endpoint — attempting to reference a deleted function
    • ASIO Attempting to reference a deleted function
    • regex_token_iterator attempting to reference a deleted function
    • C++, curious compiler error when implementing a function `int next(std::string param)`
    • C++: How to trigger a compiler error when function return value is unused?
    • Error message «undefined reference to template function passed as template parameter»
    • Moving std::list<std::unique_ptr> into vector attempts to reference a deleted function
    • Compilation error related to map and unordered_map: «attempting to reference a deleted function»
    • Why am I getting compile error «use of deleted function ‘std::unique_ptr …»
    • Compile error with pointer to template function in Visual Studio 2008
    • Compiler error with yaml-cpp — undefined reference to `YAML::detail::node_data::convert_to_map`

    More Query from same tag

    • Diff Between Call By Reference And Call By Pointer
    • Can I specify different page sizes for each page when printing programatically?
    • Initialize array in constructor’s initialization list
    • Tricky interview subject for C++
    • Writing wrappers for Python 3 vs Python 2
    • When does a static constexpr class member need an out-of-class definition?
    • Check if input is blank when input is declared as double [C++]
    • Enable C++11 support on Android
    • why we can’t initialize static variable in constructor initialization list , but we can in constructor body
    • Qt — Disable editing of cell
    • Why do references occupy memory when member of a class?
    • How can I store generic packaged_tasks in a container?
    • C++ — Using Hunspell with MFC
    • C++ pass const char* pointer array to object
    • Printing float such that exponent is marked with «*10^» instead of «e»
    • Fastest way to create random vectors for benchmarking
    • how to stop automatic conversion from int to float and vice-versa in std::map
    • Declaring normal distribution generator in .h file
    • Restrictions on local variable usage in C++?
    • What is the behavior when there are mismatched types between an extern declaration and the definition?
    • Remove a spirit qi symbol in semantic action
    • Do any automated conversion tools exist for porting C++ code to 64-bit?
    • Qt resources files with CMake and AUTORCC
    • How to resolve this linker error?
    • Is it possible to include a C header using C11 atomics without modification in C++?
    • Borland C++ Builder 5 — Cancel Via Escape Key Not Working
    • How does std::strlen wоrk internally?
    • What is «Expression SFINAE»?
    • How does virtual inheritance work?
    • How can I invoke a compile-time error via a C++ macro?

    • Forum
    • Beginners
    • error C2280 — attempting to reference a

    error C2280 — attempting to reference a deleted function

    Hi guys,

    this piece of code

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    struct Test
    {
      Test() {};
      Test(const Test&) = delete;
      Test& operator=(const Test&) = delete;
    };
    int main(int argc, char* argv[])
    {
      std::vector<Test> tests;
      tests.push_back(std::move(Test())); //gives error here
    
      return 0;
    }

    gives me error: error C2280: ‘Test::Test(const Test &)’: attempting to reference a deleted function

    I know that I’ve explicitely deleted copy constructor, but I thought I could move instance of Test() to vector insteasd of copying it. What am I doing wrong? How to move Test() to vector?

    Thank you.

    I think I understand it now.

    Deleting copy constructor explicitely caused compiler to not generate move constructor.
    So calling std::move(Test()) does not call move constructor because there is no one.

    But in that case, shouldn’t compiler inform me that move constructor is missing?

    Last edited on

    That’s right. If you want the compiler to generate the move constructor and the move assignment operator you’ll need to say so explicitly.

    1
    2
    3
    4
    5
    6
    7
    8
    struct Test
    {
      Test() {};
      Test(const Test&) = delete;
      Test& operator=(const Test&) = delete;
      Test(Test&&) = default;
      Test& operator=(Test&&) = default;
    };

    Last edited on

    > But in that case, shouldn’t compiler inform me that move constructor is missing?

    If only the copy constructor is provided, all argument categories select it (as long as it takes a reference to const, since rvalues can bind to const references), which makes copying the fallback for moving, when moving is unavailable.

    https://en.cppreference.com/w/cpp/language/move_constructor

    Thanks guys.

    Topic archived. No new replies allowed.

    Цитата
    Сообщение от Masai
    Посмотреть сообщение

    Хотя что танки, что снаряды созданы аналогично, одинаково переданы в функцию столкновений, у снарядов всё окей, а тут проблема.

    Надо увидеть объявления обоих классов, где-то в них есть разница, которая так влияет.
    Оператор= может быть недоступен по нескольким причинам, например, константы в качестве данных-членов или ссылки могут к этому привести. Смотреть надо объявления твоих классов.
    Если, например, у класса есть константы в качестве данных-членов, то компилятор не предоставляет оператор присваивания по умолчанию, т.к. константам нельзя присваивать (по умолчанию выполняется почленное присваивание для всех data members). Если тебе все-таки нужен оператор присваивания в таком классе, его нужно сделать самостоятельно.

    Цитата
    Сообщение от Masai
    Посмотреть сообщение

    в целом пока это всё не оптимально задумано

    Оно не «неоптимально», оно просто неверно. Зачем нужно было создавать вообще объект динамически, чтобы потом его по значению положить в вектор?
    Все же проще гораздо. И без утечек памяти.

    C++
    1
    2
    
    Bomb bomb(Bomb_image, angle_tower, Vector2f(Body_Corpus.getSize().x, Body_Corpus.getSize().y), pos_x, pos_y, Old_Pos, New_Pos);
    Bombs.push_back(bomb);

    Цитата
    Сообщение от Masai
    Посмотреть сообщение

    Мне просто не совсем понятно почему она нужна при удаление из вектора.

    Это очень просто: при удалении из середины вектора, чтобы заполнить образовавшееся пространство, элементы «сдвигаются». Сдвиг выполняется через копирование и присваивание элементов. Например, удалили третий, всего шесть. Третьему вызывается деструктор, затем на его месте через конструктор копирования создается новый объект на основе четвертого. Для остального «хвостика» будет выполняться присваивание: пятый присваивается четвертому, шестой — пятому, и общее количество уменьшается на 1.

    Описанный порядок лишь упрощенный пример того, как может выполняться актуализация данных в векторе после выполнения удаления из середины. В реальности, скорее всего, будет выполнено три присваивания, а деструктор вызовется у бывшего последнего элемента, после присваивания его предпоследнему (в первом варианте пришлось бы вызывать два деструктора: для удаляемого элемента, и для «лишнего» бывшего последнего). А если у данных вектора доступно перемещение (move-assignment), то будет задействовано оно, а не присваивание. Это не меняет сути, впрочем. Будь то копирование, присваивание или перемещение — они будут вызываться при некоторых операциях с вектором, удалении не с конца, добавлении элементов, операции изменения размера и т.п.



    0



    So I’m working on a simple project for learning purposes and I thought hey lets give unique_ptr’s a go because managing the deleting of pointers manually can be a pain in the ass.

    Full Error:

    Error 1 error C2280: ‘std::unique_ptr<TestScene,std::default_delete<_Ty>>::unique_ptr(const std::unique_ptr<_Ty,std::default_delete<_Ty>> &)’ : attempting to reference a deleted function D:Program Files (x86)Microsoft Visual Studio 12.0VCincludextree 893 1 New Game No Name

    Now the code I have is something pretty basic:

    #ifndef SCENE_MANAGER_H
    #define SCENE_MANAGER_H
    
    #include <map>
    #include <string>
    #include <memory>
    
    #include "scenes/test.h"
    
    class SceneManager
    {
        //map array of scene pointers
        std::map<std::string, std::unique_ptr<TestScene>> s;
    
    public:
        
        SceneManager(){};
    };
    
    #endif
    

    TestScene is a basic class that’s empty w/ an empty constructor, it’s basically like the example class below

    My header file that calls this class is just one line (it’s a member of a class to clarify)

    SceneManager m_scenes;
    

    Nothing special, I build the source and get that error using the visual studio 13 for windows desktop & tried the same using the community version (probably should be using the community version from now on anyways) — when I remove the line everything compiles properly.

    Moving forward, I spent a day googling and couldn’t find anything related to my problem that had a solution except this post: http://answersresource.wordpress.com/2014/10/22/error-c2280-attempting-to-reference-a-deleted-function-unique_ptr-related/ which doesn’t have a solution, but a similar problem nearly a month ago.

    I said screw it and created an empty project and did the following:

    #include <iostream>
    #include <memory>
    #include <utility>
    #include <map>
    
    class Maptest
    {
    public:
        Maptest(){};
    
        void testing(){
            std::cout << "Testing" << std::endl;
    	};
    };
    
    class Mapsarray
    {
    public:
        std::map<std::string, std::unique_ptr<Maptest>> maps;
    };
    
    typedef std::unique_ptr<Maptest> uptrMap;
    
    int main(int argc, char *argv)
    {
        Mapsarray myarray;
    	system("PAUSE");
    	return 0;
    }
    

    I don’t do anything special in my code and it properly builds. What am I doing wrong? and let me know if you need to see more code.

    Full source: http://inputcoffee.net/sdl2-code/

    Edit: My issue is with just the class member, I haven’t even gotten to the insertion of unique pointers yet. The first example is what I’m actually doing, how I have it setup and it throws that error, exact code usage. Which is a member of the base.h class. Now when I do it in the 2nd example it compiles with no issue except it’s the exact same code?

    Понравилась статья? Поделить с друзьями:
  • C error 4996
  • C duplicate symbol error
  • C cin int error
  • C builder socket error
  • C builder error detected lme200