官术网_书友最值得收藏!

Pitfalls with non-noexcept move constructors

Recall the implementation of vector::resize() from section Resizing a std::vector. When the vector resizes, it reallocates its underlying array and moves its elements into the new array--unless the element type is not "nothrow move-constructible," in which case it copies its elements! What this means is that resizing a vector of your own class type will be unnecessarily "pessimized" unless you go out of your way to specify that your move constructor is noexcept.

Consider the following class definitions:

    struct Bad {
int x = 0;
Bad() = default;
Bad(const Bad&) { puts("copy Bad"); }
Bad(Bad&&) { puts("move Bad"); }
};

struct Good {
int x = 0;
Good() = default;
Good(const Good&) { puts("copy Good"); }
Good(Good&&) noexcept { puts("move Good"); }
};

class ImplicitlyGood {
std::string x;
Good y;
};

class ImplicitlyBad {
std::string x;
Bad y;
};

We can test the behavior of these classes in isolation using a test harness such as the following. Running test() will print "copy Bad--move Good--copy Bad--move Good." What an appropriate mantra!

    template<class T>
void test_resizing()
{
std::vector<T> vec(1);
// Force a reallocation on the vector.
vec.resize(vec.capacity() + 1);
}

void test()
{
test_resizing<Good>();
test_resizing<Bad>();
test_resizing<ImplicitlyGood>();
test_resizing<ImplicitlyBad>();
}

This is a subtle and arcane point, but it can have a major effect on the efficiency of your C++ code in practice. A good rule of thumb is: Whenever you declare your own move constructor or swap function, make sure you declare it noexcept.

主站蜘蛛池模板: 车险| 富民县| 勃利县| 西青区| 霞浦县| 始兴县| 平乐县| 涿州市| 高阳县| 庆阳市| 个旧市| 东兰县| 磐石市| 呼玛县| 克什克腾旗| 青川县| 韶山市| 奈曼旗| 米泉市| 紫金县| 溧水县| 赞皇县| 陇川县| 琼海市| 宿迁市| 留坝县| 灌南县| 抚顺市| 黄骅市| 淮北市| 兴文县| 乐东| 德兴市| 潞西市| 容城县| 吉林省| 安康市| 崇明县| 嘉祥县| 咸丰县| 湟源县|