哪些存储类型不完整的STL数据结构可以作为class成员?
Which STL data structures with an incomplete type stored can be used as a class member?
据我所知,自从 C++17 以来,一些 STL 数据结构可能 "exist" 使用不完整的类型作为描述存储类型的模板参数。例如,如果 class 的所有属性(需要Incomplete
的定义)在单独的 .cpp 文件中实现:
class Incomplete;
using Complete = int;
class Foo {
private:
std::unique_ptr<Incomplete> u_p;
std::vector<Incomplete> v;
std::deque<Incomplete> d;
std::list<Incomplete> l;
std::set<Incomplete> s;
std::unordered_map<Complete, Complete> u_m_cc;
std::unordered_map<Complete, Incomplete> u_m_ci;
std::unordered_map<Incomplete, Complete> u_m_ic;
std::unordered_map<Incomplete, Incomplete> u_m_ii;
public:
// implemented in a separate .cpp which has Incomplete defined:
Foo();
Foo(Foo&&);
Foo& operator=(Foo&&);
Foo(Foo const&);
Foo& operator=(Foo const&);
~Foo();
};
那么,上面列出的哪些数据成员适用于这种用法?其他数据结构、智能指针等呢?
since C++17 some STL data structures may "exist" with an incomplete type as the template parameter which describes the type stored.
这是不正确的。
自 C++17 起,某些 STL 类型可能声明时使用不完整的类型作为模板参数。
当类型实例化时,类型必须完整。
例如:(未经测试的代码)
struct T; // incomplete
using TV = std::vector<T>; // declared a type using incomplete type T; fine.
TV tv0; // attempt to declare a variable of type TV; fails to compile.
struct T { int v; }; // T is now complete
TV tv1; // compiles
假设 类 成员中的 none 被显式或隐式使用,直到类型完成:
从 C++11 开始,std::unique_ptr
和 std::shared_ptr
的模板参数总是不完整的,请分别参见 [unique.ptr]/5 and [util.smartptr.shared]/2。
容器中不完整类型的支持已随 N4510 添加到 C++17,但仅限于
std::vector
std::list
std::forward_list
并且仅当使用的分配器满足分配器完整性要求时,即即使值类型本身不完整,分配器类型X
本身也是std::allocator_traits<X>
的所有成员都是完整类型,::value_type
除外。默认分配器 std::allocator
满足这些要求。
None 的其他容器可以与不完整的类型一起使用。根据上面链接的提案,范围仅限于这三个容器“作为第一步”,因为主要实现已经支持它。
据我所知,自从 C++17 以来,一些 STL 数据结构可能 "exist" 使用不完整的类型作为描述存储类型的模板参数。例如,如果 class 的所有属性(需要Incomplete
的定义)在单独的 .cpp 文件中实现:
class Incomplete;
using Complete = int;
class Foo {
private:
std::unique_ptr<Incomplete> u_p;
std::vector<Incomplete> v;
std::deque<Incomplete> d;
std::list<Incomplete> l;
std::set<Incomplete> s;
std::unordered_map<Complete, Complete> u_m_cc;
std::unordered_map<Complete, Incomplete> u_m_ci;
std::unordered_map<Incomplete, Complete> u_m_ic;
std::unordered_map<Incomplete, Incomplete> u_m_ii;
public:
// implemented in a separate .cpp which has Incomplete defined:
Foo();
Foo(Foo&&);
Foo& operator=(Foo&&);
Foo(Foo const&);
Foo& operator=(Foo const&);
~Foo();
};
那么,上面列出的哪些数据成员适用于这种用法?其他数据结构、智能指针等呢?
since C++17 some STL data structures may "exist" with an incomplete type as the template parameter which describes the type stored.
这是不正确的。
自 C++17 起,某些 STL 类型可能声明时使用不完整的类型作为模板参数。
当类型实例化时,类型必须完整。
例如:(未经测试的代码)
struct T; // incomplete
using TV = std::vector<T>; // declared a type using incomplete type T; fine.
TV tv0; // attempt to declare a variable of type TV; fails to compile.
struct T { int v; }; // T is now complete
TV tv1; // compiles
假设 类 成员中的 none 被显式或隐式使用,直到类型完成:
从 C++11 开始,std::unique_ptr
和 std::shared_ptr
的模板参数总是不完整的,请分别参见 [unique.ptr]/5 and [util.smartptr.shared]/2。
容器中不完整类型的支持已随 N4510 添加到 C++17,但仅限于
std::vector
std::list
std::forward_list
并且仅当使用的分配器满足分配器完整性要求时,即即使值类型本身不完整,分配器类型X
本身也是std::allocator_traits<X>
的所有成员都是完整类型,::value_type
除外。默认分配器 std::allocator
满足这些要求。
None 的其他容器可以与不完整的类型一起使用。根据上面链接的提案,范围仅限于这三个容器“作为第一步”,因为主要实现已经支持它。