C++ 删除默认构造函数会导致STL容器中的默认分配器出现问题
我有一个类似这样的类:C++ 删除默认构造函数会导致STL容器中的默认分配器出现问题,c++,oop,constructor,stl,allocator,C++,Oop,Constructor,Stl,Allocator,我有一个类似这样的类: class PasswordCategory { public: PasswordCategory(const std::string&); ~PasswordCategory(); PasswordCategory() = delete; ... } 这会导致与分配器相关的编译器错误: 错误C2280:'PasswordCategory::PasswordCategory(void)':正在尝试 引用已删除函数的步骤文件:xm
class PasswordCategory
{
public:
PasswordCategory(const std::string&);
~PasswordCategory();
PasswordCategory() = delete;
...
}
这会导致与分配器相关的编译器错误:
错误C2280:'PasswordCategory::PasswordCategory(void)':正在尝试
引用已删除函数的步骤文件:xmemory0:577 IDE是VS2013社区 我假设发生这种情况是因为我在其他地方使用这些类别的向量
std::vector<PasswordCategory> m_categories;
std::向量m_类;
我只使用emplace_back(string)将元素插入其中,但是,似乎PasswordCategory的默认分配器正在尝试使用PasswordCategory的默认构造函数,但由于该构造函数已被删除,因此会抛出一个错误
如果我提供默认构造函数,一切都很好,但我想知道如果没有默认构造函数,我如何缓解这个问题
我想到了以下解决方案:这是我的一个小项目,为了更好地理解C++,在这里我试图避免大多数常见的陷阱,并使所有的事情尽可能可靠,这样当我要做一个更大的项目时,我就更容易避免这些常见的陷阱。我试着用不同的方式表达这个问题,但没有找到我问题的答案,所以我只问我自己的问题。原则上,你不能:标准容器要求包含的对象是默认可构造的。(见迈克·西摩的评论) 原则上,您应该能够,除非您在内部使用需要默认构造的操作 这就是说,您可以简单地创建一个空构造函数(默认成员为sane/使用一些参数调用另一个构造函数)。如果正确编写客户机代码,则不会遇到使用默认值初始化的对象
需要默认构造对象的操作通常是调整大小,以及其他一些需要创建内部对象的操作(即,除非您想保留一个元素并在不显式初始化它的情况下使用它,否则您不应该有问题).
std::vector
本身不要求t
为DefaultConstructible
类型:
<强>直到C++ 11:
T必须满足可复制分配和可复制构造的要求<强> C++ 11:< /强> < /P> 对构件施加的要求取决于对容器执行的实际操作。通常,要求元素类型为完整类型并满足可擦除的要求,但许多成员函数的要求更为严格
有关详细信息,请参阅 然而,您可以在容器上执行操作,这涉及到创建隐式实例,这就是为什么会出现此错误。如果您可以跟踪并消除它们,那么一切都应该正常工作,因为如果不使用默认构造函数,就不需要它 考虑到你的建议: 1。为构建类的类提供自定义分配器 这不会有任何帮助-std::allocator
不负责默认的构造元素,因为它只是不定义这样的功能。看
编辑
这里有点小错误,我没有注意到C++ 11中的小变化:
<强>直到C++ 11
void construct( pointer p, const_reference val );
template< class U, class... Args >
void construct( U* p, Args&&... args );
<强> C++ 11 < /强>
void construct( pointer p, const_reference val );
template< class U, class... Args >
void construct( U* p, Args&&... args );
template
无效构造(U*p、参数和参数);
2。提供默认构造函数,该构造函数只调用我的另一个构造函数,并带有一些参数
这也不能解决这个参数是非可选的,不应该被默认的问题。
这也不是完全可移植的。有些编译器(如VC11)不支持委托构造函数
3.使用引用向量或指针而不是值向量
这似乎是最合理的解决方案,但是它引入了手动管理内存的需求,除非我们使用unique_ptr或类似的东西。
不完全有效-无法创建引用的容器。最接近的解决方案是容器,它容纳s。原始/智能指针的容器也是一个选项,但这就是问题所在,事情开始变得一团糟
另外,在您的原始代码中,不需要声明已删除的默认构造函数-如果您声明any构造函数,这意味着没有默认构造函数(除非您定义它),编译器不会生成任何构造函数。您能确切地告诉我们您是如何处理导致错误的向量吗?如果实现符合C++11/14,只要您不做任何特别需要默认构造函数的事情(例如,使用单个参数调用
resize
)。定义一个空向量,并使用适当的构造函数参数调用emplace\u back
,应该可以。啊,这很奇怪。读了你的评论后,我终于找到了罪犯。我正在使用0参数初始化向量:PasswordManage