首页 > 解决方案 > 矢量调整大小似乎需要 C++ 中的默认构造函数 >= 11

问题描述

我有以下测试代码,我在其中创建了一个std::vectorfoo,然后resize是它。

#include <iostream>
#include <vector>
#include <algorithm>

class foo {
public:
    foo(int n) : num(n) {}
    //foo() : num(42) {}
    ~foo () { std::cout << "destructor" << std::endl; }
    void print() { std::cout << num << std::endl; }
protected:
    int num;
};


int main()
{
    std::vector<foo> v = { 3,2,1,7,5,1,8,9 };
    v.resize(2);
        
    for (auto obj: v)
        obj.print();

    return 0;
}

当默认构造函数被注释掉时,我得到编译错误:

错误 C2512 'foo::foo': 没有合适的默认构造函数可用

我使用 Visual Studio 2019 编译,语言设置为 C++ 17。我不理解此错误消息,因为在 C++ >= 11 中,std::vector::resize具有以下重载:

void resize (size_type n)

所以我应该能够在没有默认值或没有定义默认构造函数的情况下调用它。这是怎么回事?

标签: c++

解决方案


是和不是。

您当前使用的重载确实如此。然而,还有第二个重载,您可以在其中为新元素提供一个值 - 即使您知道要将其调整为更小的尺寸,这也是必需的。

constexpr void resize( size_type count, const value_type& value );

所以要么:

v.resize(2, 0);

erase您不想保留的元素。这样,您不需要提供值。

v.erase(std::next(v.begin(), 2), v.end());

如果您想resize()用作调整大小的主要方法,您可以添加一个辅助函数,该函数仅用erase()作不可默认构造的类型的后备。

#include <type_traits>

template <typename C>
void downsize(C& c, std::size_t size) {
    if (size < c.size()) {
        if constexpr (std::is_default_constructible_v<typename C::value_type>) {
            c.resize(size);
        } else {
            c.erase(std::next(c.begin(), size), c.end());
        }
    }
}

推荐阅读