Skip to content

Commit aab5c29

Browse files
Merge pull request MicrosoftDocs#4813 from MicrosoftDocs/main638356731646792016sync_temp
For protected branch, push strategy should use PR and merge to target branch method to work around git push error
2 parents f8c73da + bfa85d2 commit aab5c29

9 files changed

+258
-66
lines changed

docs/cpp/explicitly-defaulted-and-deleted-functions.md

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,14 @@
22
description: "Learn more about: Explicitly Defaulted and Deleted Functions"
33
title: "Explicitly Defaulted and Deleted Functions"
44
ms.date: "11/04/2016"
5-
ms.assetid: 5a588478-fda2-4b3f-a279-db3967f5e07e
65
---
76
# Explicitly Defaulted and Deleted Functions
87

9-
In C++11, defaulted and deleted functions give you explicit control over whether the special member functions are automatically generated. Deleted functions also give you simple language to prevent problematic type promotions from occurring in arguments to functions of all types—special member functions, as well as normal member functions and non-member functions—which would otherwise cause an unwanted function call.
8+
In C++11, defaulted and deleted functions give you explicit control over whether the special member functions are automatically generated. Deleted functions also give you simple language to prevent problematic type promotions from occurring in arguments to functions of all types—special member functions, and normal member functions and nonmember functions—which would otherwise cause an unwanted function call.
109

1110
## Benefits of explicitly defaulted and deleted functions
1211

13-
In C++, the compiler automatically generates the default constructor, copy constructor, copy-assignment operator, and destructor for a type if it does not declare its own. These functions are known as the *special member functions*, and they are what make simple user-defined types in C++ behave like structures do in C. That is, you can create, copy, and destroy them without any additional coding effort. C++11 brings move semantics to the language and adds the move constructor and move-assignment operator to the list of special member functions that the compiler can automatically generate.
12+
In C++, the compiler automatically generates the default constructor, copy constructor, copy-assignment operator, and destructor for a type if it doesn't declare its own. These functions are known as the *special member functions*, and they're what make simple user-defined types in C++ behave like structures do in C. That is, you can create, copy, and destroy them without extra coding effort. C++11 brings move semantics to the language and adds the move constructor and move-assignment operator to the list of special member functions that the compiler can automatically generate.
1413

1514
This is convenient for simple types, but complex types often define one or more of the special member functions themselves, and this can prevent other special member functions from being automatically generated. In practice:
1615

@@ -36,11 +35,11 @@ This is convenient for simple types, but complex types often define one or more
3635
> - If a copy constructor or destructor is explicitly declared, then automatic generation of the copy-assignment operator is deprecated.
3736
> - If a copy-assignment operator or destructor is explicitly declared, then automatic generation of the copy constructor is deprecated.
3837
>
39-
> In both cases, Visual Studio continues to automatically generate the necessary functions implicitly, and does not emit a warning.
38+
> In both cases, Visual Studio continues to automatically generate the necessary functions implicitly, and doesn't emit a warning by default. Since Visual Studio 2022 version 17.7, [C5267](../error-messages/compiler-warnings/c5267.md) can be enabled to emit a warning.
4039
41-
The consequences of these rules can also leak into object hierarchies. For example, if for any reason a base class fails to have a default constructor that's callable from a deriving class—that is, a **`public`** or **`protected`** constructor that takes no parameters—then a class that derives from it cannot automatically generate its own default constructor.
40+
The consequences of these rules can also leak into object hierarchies. For example, if for any reason a base class fails to have a default constructor that's callable from a deriving class—that is, a **`public`** or **`protected`** constructor that takes no parameters—then a class that derives from it can't automatically generate its own default constructor.
4241

43-
These rules can complicate the implementation of what should be straight-forward, user-defined types and common C++ idioms—for example, making a user-defined type non-copyable by declaring the copy constructor and copy-assignment operator privately and not defining them.
42+
These rules can complicate the implementation of what should be straight-forward, user-defined types and common C++ idioms—for example, making a user-defined type noncopyable by declaring the copy constructor and copy-assignment operator privately and not defining them.
4443

4544
```cpp
4645
struct noncopyable
@@ -53,17 +52,17 @@ private:
5352
};
5453
```
5554
56-
Before C++11, this code snippet was the idiomatic form of non-copyable types. However, it has several problems:
55+
Before C++11, this code snippet was the idiomatic form of noncopyable types. However, it has several problems:
5756
5857
- The copy constructor has to be declared privately to hide it, but because it's declared at all, automatic generation of the default constructor is prevented. You have to explicitly define the default constructor if you want one, even if it does nothing.
5958
60-
- Even if the explicitly-defined default constructor does nothing, it's considered non-trivial by the compiler. It's less efficient than an automatically generated default constructor and prevents `noncopyable` from being a true POD type.
59+
- Even if the explicitly defined default constructor does nothing, the compiler considers it to be nontrivial. It's less efficient than an automatically generated default constructor and prevents `noncopyable` from being a true POD type.
6160
62-
- Even though the copy constructor and copy-assignment operator are hidden from outside code, the member functions and friends of `noncopyable` can still see and call them. If they are declared but not defined, calling them causes a linker error.
61+
- Even though the copy constructor and copy-assignment operator are hidden from outside code, the member functions and friends of `noncopyable` can still see and call them. If they're declared but not defined, calling them causes a linker error.
6362
64-
- Although this is a commonly accepted idiom, the intent is not clear unless you understand all of the rules for automatic generation of the special member functions.
63+
- Although this is a commonly accepted idiom, the intent isn't clear unless you understand all of the rules for automatic generation of the special member functions.
6564
66-
In C++11, the non-copyable idiom can be implemented in a way that is more straightforward.
65+
In C++11, the noncopyable idiom can be implemented in a way that is more straightforward.
6766
6867
```cpp
6968
struct noncopyable
@@ -78,17 +77,17 @@ Notice how the problems with the pre-C++11 idiom are resolved:
7877

7978
- Generation of the default constructor is still prevented by declaring the copy constructor, but you can bring it back by explicitly defaulting it.
8079

81-
- Explicitly defaulted special member functions are still considered trivial, so there is no performance penalty, and `noncopyable` is not prevented from being a true POD type.
80+
- Explicitly defaulted special member functions are still considered trivial, so there's no performance penalty, and `noncopyable` isn't prevented from being a true POD type.
8281

83-
- The copy constructor and copy-assignment operator are public but deleted. It is a compile-time error to define or call a deleted function.
82+
- The copy constructor and copy-assignment operator are public but deleted. It's a compile-time error to define or call a deleted function.
8483

8584
- The intent is clear to anyone who understands `=default` and `=delete`. You don't have to understand the rules for automatic generation of special member functions.
8685

87-
Similar idioms exist for making user-defined types that are non-movable, that can only be dynamically allocated, or that cannot be dynamically allocated. Each of these idioms have pre-C++11 implementations that suffer similar problems, and that are similarly resolved in C++11 by implementing them in terms of defaulted and deleted special member functions.
86+
Similar idioms exist for making user-defined types that are nonmovable, that can only be dynamically allocated, or that can't be dynamically allocated. Each of these idioms have pre-C++11 implementations that suffer similar problems, and that are similarly resolved in C++11 by implementing them in terms of defaulted and deleted special member functions.
8887

8988
## Explicitly defaulted functions
9089

91-
You can default any of the special member functions—to explicitly state that the special member function uses the default implementation, to define the special member function with a non-public access qualifier, or to reinstate a special member function whose automatic generation was prevented by other circumstances.
90+
You can default any of the special member functions—to explicitly state that the special member function uses the default implementation, to define the special member function with a nonpublic access qualifier, or to reinstate a special member function whose automatic generation was prevented by other circumstances.
9291

9392
You default a special member function by declaring it as in this example:
9493

@@ -109,7 +108,7 @@ Because of the performance benefits of trivial special member functions, we reco
109108

110109
## Deleted functions
111110

112-
You can delete special member functions as well as normal member functions and non-member functions to prevent them from being defined or called. Deleting of special member functions provides a cleaner way of preventing the compiler from generating special member functions that you don't want. The function must be deleted as it is declared; it cannot be deleted afterwards in the way that a function can be declared and then later defaulted.
111+
You can delete special member functions and normal member functions and nonmember functions to prevent them from being defined or called. Deleting of special member functions provides a cleaner way of preventing the compiler from generating special member functions that you don't want. The function must be deleted as it's declared; it can't be deleted afterwards in the way that a function can be declared and then later defaulted.
113112

114113
```cpp
115114
struct widget
@@ -119,15 +118,15 @@ struct widget
119118
};
120119
```
121120

122-
Deleting of normal member function or non-member functions prevents problematic type promotions from causing an unintended function to be called. This works because deleted functions still participate in overload resolution and provide a better match than the function that could be called after the types are promoted. The function call resolves to the more-specific—but deleted—function and causes a compiler error.
121+
Deleting of normal member function or nonmember functions prevents problematic type promotions from causing an unintended function to be called. This works because deleted functions still participate in overload resolution and provide a better match than the function that could be called after the types are promoted. The function call resolves to the more-specific—but deleted—function and causes a compiler error.
123122

124123
```cpp
125124
// deleted overload prevents call through type promotion of float to double from succeeding.
126125
void call_with_true_double_only(float) =delete;
127126
void call_with_true_double_only(double param) { return; }
128127
```
129128
130-
Notice in the preceding sample that calling `call_with_true_double_only` by using a **`float`** argument would cause a compiler error, but calling `call_with_true_double_only` by using an **`int`** argument would not; in the **`int`** case, the argument will be promoted from **`int`** to **`double`** and successfully call the **`double`** version of the function, even though that might not be what's intended. To ensure that any call to this function by using a non-double argument causes a compiler error, you can declare a template version of the function that's deleted.
129+
Notice in the preceding sample that calling `call_with_true_double_only` by using a **`float`** argument would cause a compiler error, but calling `call_with_true_double_only` by using an **`int`** argument wouldn't; in the **`int`** case, the argument will be promoted from **`int`** to **`double`** and successfully call the **`double`** version of the function, even though that might not be what you intend. To ensure that any call to this function by using a non-double argument causes a compiler error, you can declare a template version of the deleted function.
131130
132131
```cpp
133132
template < typename T >
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
---
2+
title: "Compiler warning 3 C5267"
3+
description: Learn about compiler warning C5267
4+
ms.date: 11/08/2023
5+
f1_keywords: ["C5267"]
6+
helpviewer_keywords: ["C5267"]
7+
---
8+
# Compiler warning C5267
9+
10+
> definition of implicit copy constructor/assignment operator for '*type*' is deprecated because it has a user-provided assignment operator/copy constructor
11+
12+
## Remarks
13+
14+
The C++ Standard deprecated (but didn't remove) the implicit generation of copy and assignment operators under some conditions. The MSVC compiler still generates the copy and assignment operators under those conditions, but may change its behavior in the future if the standard removes the deprecated behavior. The purpose of this warning is to help future proof your code if the committee decides to remove this functionality.
15+
16+
The relevant sections in the C++ standard are:
17+
- [class.copy.ctor paragraph 6](https://eel.is/c++draft/class.copy.ctor#6), which says: "If the class definition does not explicitly declare a copy constructor, a nonexplicit 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 defaulted. The latter case is deprecated if the class has a user-declared copy assignment operator or a user-declared destructor."
18+
- [Annex D D.8](https://eel.is/c++draft/depr.impldec#1), which says: "The implicit definition of a copy constructor as defaulted is deprecated if the class has a user-declared copy assignment operator or a user-declared destructor. The implicit definition of a copy assignment operator as defaulted is deprecated if the class has a user-declared copy constructor or a user-declared destructor. It's possible that future versions of C++ will specify that these implicit definitions are deleted."
19+
20+
## Example
21+
22+
The following code shows warning C5267 when an implicitly generated special function is called but isn't explicitly defined:
23+
24+
```cpp
25+
// C5267.cpp
26+
// compile using: /W4 /w45267
27+
struct CopyCtorOnly
28+
{
29+
CopyCtorOnly() = default;
30+
CopyCtorOnly(const CopyCtorOnly&) {} // C5267
31+
};
32+
33+
struct CopyAssignOpOnly
34+
{
35+
CopyAssignOpOnly() = default;
36+
CopyAssignOpOnly& operator=(const CopyAssignOpOnly&) // C5267
37+
{
38+
return *this;
39+
}
40+
};
41+
42+
int main()
43+
{
44+
CopyCtorOnly a1, a2;
45+
a1 = a2; // Calls deprecated copy assignment operator
46+
47+
CopyAssignOpOnly b1;
48+
CopyAssignOpOnly b2 = b1; // Calls deprecated copy constructor
49+
}
50+
```
51+
52+
To resolve this issue, explicitly define the missing copy constructor or copy assignment operator.
53+
54+
## See also
55+
56+
[Explicitly Defaulted and Deleted Functions](../../cpp/explicitly-defaulted-and-deleted-functions.md)

docs/error-messages/compiler-warnings/compiler-warning-levels-3-and-4-c4244.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@ ms.date: "11/6/2023"
99

1010
An integer type is converted to a smaller integer type.
1111
- This is a level-4 warning if *type1* is a signed or unsigned **`int`** and *type2* is a smaller, such as a signed or unsigned **`short`**.
12-
- It is a level 3 warning if a value of type [`__int64`](../../cpp/int8-int16-int32-int64.md) or **`unsigned __int64`** is assigned to a signed or unsigned **`int`**. A possible loss of data may have occurred due to a narrowing conversion, which might lead to unexpected results.
12+
- It's a level 3 warning if a value of type [`__int64`](../../cpp/int8-int16-int32-int64.md) or **`unsigned __int64`** is assigned to a signed or unsigned **`int`**. A possible loss of data may have occurred due to a narrowing conversion, which might lead to unexpected results.
1313

14-
To fix this warning, either change your program to use compatible types, or add logic that ensures that the range of possible values is compatible with the types you are using. If the conversion is intended, use an explicit cast to silence the warning.
14+
To fix this warning, either change your program to use compatible types, or add logic that ensures that the range of possible values is compatible with the types you're using. If the conversion is intended, use an explicit cast to silence the warning.
1515

16-
C4244 can also appear when the warning level is 2; see [Compiler Warning (level 2) C4244](../../error-messages/compiler-warnings/compiler-warning-level-2-c4244.md) for more information.
16+
C4244 can also appear when the warning level is 2. For more information, see [Compiler Warning (level 2) C4244](../../error-messages/compiler-warnings/compiler-warning-level-2-c4244.md).
1717

1818
The following sample generates C4244:
1919

@@ -50,7 +50,7 @@ int main() {
5050
}
5151
```
5252

53-
Warning C4244 can occur when building code for 64-bit targets that does not generate the warning when building for 32-bit targets. For example, pointer arithmetic results in a 32-bit quantity on 32-bit platforms, but a 64-bit quantity on 64-bit platforms.
53+
Warning C4244 can occur when building code for 64-bit targets that doesn't generate the warning when building for 32-bit targets. For example, pointer arithmetic results in a 32-bit quantity on 32-bit platforms, but a 64-bit quantity on 64-bit platforms.
5454

5555
The following sample generates C4244 when compiled for 64-bit targets:
5656

0 commit comments

Comments
 (0)