c++03 中的复制省略
copy elision in c++03
在某些情况下,Copy-elision 在 c++17 中是强制性的,而在 c++11/14 中是允许的。这尤其涉及复制初始化。
比如下面的程序
#include <iostream>
struct A
{
explicit A(int){ std::cout << "conversion" << std::endl; }
A(const A&) { std::cout << "copy constructor" << std::endl; }
};
int main()
{
A b = A(3);
}
预期在 c++17 中产生输出
conversion
在 c++11/14 中可能会产生相同的输出。考虑到这些问题,gcc 10.1.0 和 clang 11.1.0 也会使用 -std=c++11
或 -std=c++14
生成上述输出,除非使用 -fno-elide-constructors
.[=18 显式禁用可选的构造函数省略=]
但是c++03标准呢?是否允许在复制初始化中省略复制构造函数?具有 -std=c++03
的 gcc 和 clang 总是抑制复制构造函数(除非指定 -fno-elide-constructors
)。
是的,在 C++03 和 C++98 中允许复制省略。那是 C++98 和 C++03 的段落:
Non-mandatory elision of copy operations
Under the following circumstances, the compilers are permitted, but
not required to omit the copy construction of
class objects even if the copy constructor and the
destructor have observable side-effects. The objects are constructed
directly into the storage where they would otherwise be copied
to. This is an optimization: even when it takes place and the
copy constructor is not called, it still must be
present and accessible (as if no optimization happened at all),
otherwise the program is ill-formed:
In a return statement, when the operand is the name of a non-volatile object with automatic storage duration, which isn't a
function parameter or a catch clause parameter, and which is of the
same class type (ignoring cv-qualification) as the function return
type. This variant of copy elision is known as NRVO, "named return
value optimization".
In the initialization of an object, when the source object is a nameless temporary and is of the same class type (ignoring
cv-qualification) as the target object. When the nameless temporary is
the operand of a return statement, this variant of copy elision is
known as RVO, "return value optimization".
When copy elision occurs, the implementation treats the source and target of the omitted copy operation as simply two different ways of referring to the same object, and the destruction of that object occurs at the later of the times when the two objects would have been destroyed without the optimization
我删除了仅自 C++11 起有效的所有内容。
C++98、C++03 和 C++11 之间关于省略的唯一区别是移动操作和异常处理。
Copy-elision 在 c++17 中是强制性的,而在 c++11/14 中是允许的。这尤其涉及复制初始化。 比如下面的程序
#include <iostream>
struct A
{
explicit A(int){ std::cout << "conversion" << std::endl; }
A(const A&) { std::cout << "copy constructor" << std::endl; }
};
int main()
{
A b = A(3);
}
预期在 c++17 中产生输出
conversion
在 c++11/14 中可能会产生相同的输出。考虑到这些问题,gcc 10.1.0 和 clang 11.1.0 也会使用 -std=c++11
或 -std=c++14
生成上述输出,除非使用 -fno-elide-constructors
.[=18 显式禁用可选的构造函数省略=]
但是c++03标准呢?是否允许在复制初始化中省略复制构造函数?具有 -std=c++03
的 gcc 和 clang 总是抑制复制构造函数(除非指定 -fno-elide-constructors
)。
是的,在 C++03 和 C++98 中允许复制省略。那是 C++98 和 C++03 的段落:
Non-mandatory elision of copy operations
Under the following circumstances, the compilers are permitted, but not required to omit the copy construction of class objects even if the copy constructor and the destructor have observable side-effects. The objects are constructed directly into the storage where they would otherwise be copied to. This is an optimization: even when it takes place and the copy constructor is not called, it still must be present and accessible (as if no optimization happened at all), otherwise the program is ill-formed:
In a return statement, when the operand is the name of a non-volatile object with automatic storage duration, which isn't a function parameter or a catch clause parameter, and which is of the same class type (ignoring cv-qualification) as the function return type. This variant of copy elision is known as NRVO, "named return value optimization".
In the initialization of an object, when the source object is a nameless temporary and is of the same class type (ignoring cv-qualification) as the target object. When the nameless temporary is the operand of a return statement, this variant of copy elision is known as RVO, "return value optimization".
When copy elision occurs, the implementation treats the source and target of the omitted copy operation as simply two different ways of referring to the same object, and the destruction of that object occurs at the later of the times when the two objects would have been destroyed without the optimization
我删除了仅自 C++11 起有效的所有内容。
C++98、C++03 和 C++11 之间关于省略的唯一区别是移动操作和异常处理。