在没有 copying/moving 元素的情况下初始化 std::array
initialize std::array without copying/moving elements
#include <iostream>
#include <string>
#include <array>
class C {
private:
std::string a;
std::string b;
std::string c;
public:
C(std::string a_, std::string b_, std::string c_) : a{a_},b{b_},c{c_} {}
~C(){};
C(const C&) =delete;
C(const C&&) =delete;
const C& operator=(const C&) =delete;
const C& operator=(const C&&) =delete;
};
std::array<C,2> array = {C("","",""),C("","","")};
int main()
{}
这将无法编译(Android Studio with NDK and clang)并出现 "call to deleted constructor of c" 错误。我知道我可以使用 std::vector
和 emplace_back()
直接在容器内构造元素,但在我的代码中我只想使用固定大小的容器和 non-copyable/moveable 对象进行优化。我可能在这里遗漏了一些基本的东西,但是没有一种方法可以初始化 std::array
而不必首先构造各个元素然后将它们复制到那里吗?
您可以使用大括号括起来的初始值设定项而不是临时 c
对象:
std::array<c,2> array = {{{"",""},{"",""}}};
或
std::array<c,2> array{{{"",""},{"",""}}};
从 C++17 开始,对于某些特定情况 copy elision 是有保证的。
Under the following circumstances, the compilers are required to omit
the copy- and move- constructors of class objects even if copy/move
constructor and the destructor have observable side-effects:
In initialization, if the initializer expression is a prvalue and the cv-unqualified version of the source type is the same class as the
class of the destination, the initializer expression is used to
initialize the destination object:
T x = T(T(T())); // only one call to default constructor of T, to initialize x
对于这些情况,copy/move 构造函数不需要可访问。
When copy-elision takes place (until C++17)
In those cases where
copy-elision is not guaranteed, if it takes place (since C++17)
and
the copy-/move-constructor is not called, it must be present and
accessible (as if no optimization happened at all), otherwise the
program is ill-formed.
#include <iostream>
#include <string>
#include <array>
class C {
private:
std::string a;
std::string b;
std::string c;
public:
C(std::string a_, std::string b_, std::string c_) : a{a_},b{b_},c{c_} {}
~C(){};
C(const C&) =delete;
C(const C&&) =delete;
const C& operator=(const C&) =delete;
const C& operator=(const C&&) =delete;
};
std::array<C,2> array = {C("","",""),C("","","")};
int main()
{}
这将无法编译(Android Studio with NDK and clang)并出现 "call to deleted constructor of c" 错误。我知道我可以使用 std::vector
和 emplace_back()
直接在容器内构造元素,但在我的代码中我只想使用固定大小的容器和 non-copyable/moveable 对象进行优化。我可能在这里遗漏了一些基本的东西,但是没有一种方法可以初始化 std::array
而不必首先构造各个元素然后将它们复制到那里吗?
您可以使用大括号括起来的初始值设定项而不是临时 c
对象:
std::array<c,2> array = {{{"",""},{"",""}}};
或
std::array<c,2> array{{{"",""},{"",""}}};
从 C++17 开始,对于某些特定情况 copy elision 是有保证的。
Under the following circumstances, the compilers are required to omit the copy- and move- constructors of class objects even if copy/move constructor and the destructor have observable side-effects:
In initialization, if the initializer expression is a prvalue and the cv-unqualified version of the source type is the same class as the class of the destination, the initializer expression is used to initialize the destination object:
T x = T(T(T())); // only one call to default constructor of T, to initialize x
对于这些情况,copy/move 构造函数不需要可访问。
When copy-elision takes place (until C++17)
In those cases where copy-elision is not guaranteed, if it takes place (since C++17)
and the copy-/move-constructor is not called, it must be present and accessible (as if no optimization happened at all), otherwise the program is ill-formed.