我如何设法在标准容器中存储引用类型?
How did I manage to store a reference type in a standard container?
在尝试使用c++ 11智能指针和容器类时,我编写了两段代码,基本上可以归结为以下内容:
class Foo { ... };
typedef std::unique_ptr<Foo> FooPtr;
// First attempt; this did _not_ compile
typedef std::unordered_map<int, FooPtr> IntToFooMap;
// Second attempt; this _did_ compile
typedef std::unordered_map<int, const FooPtr &> IntToFooMap;
// here is the declaration causing the error in the second case:
IntToFooMap m {
{ 41, FooPtr(new Foo()) }
};
正如你所看到的,首先我尝试定义一个FooPtr
的无序映射,它没有编译,因为FooPtr
是一个不可复制的std::unique_ptr
(它有一个删除的复制构造函数)。
更准确地说,是使用初始化列表对map进行初始化导致了错误。
然而,令我非常惊讶的是,我将无序映射的value_type
定义为FooPtr
的const引用的第二个版本确实编译了。
直到今天,我一直认为在标准容器中存储引用类型的值是不可能的。虽然这种行为在某种程度上是可以直观理解的,因为声明(const)引用可以防止(否则是禁止的)复制unique_ptr
,但我仍然不完全理解这是如何工作的,或者为什么这样做。如果它能工作,当然;如果这只是一个微妙的角落情况,导致未定义的行为,我不会感到惊讶。
您违反了库的约束。这将导致未定义的行为。库可能会也可能不会检测到它是引用。
引用的问题在于标准库允许假定容器拥有保存元素值的对象,因此可以调用其析构函数,特别是它可以这样做:allocator_traits<A>::destroy(m, p) // m is the allocator, p points to object.
我没有注意到语言明确要求std::[unordered_]map
中的映射类型是对象类型,但是你必须非常小心地避免operator[]
,因为它会试图默认构造value_type
,即std::pair<int, FooPtr const &>
。对于无序容器,为了使用动态数组作为散列桶,还需要value_type
的CopyAssignability,尽管引用是可CopyAssignable的(副本转移到被引用的对象),但包含引用的pair不是。
我怀疑库的意图是允许在那里引用,但是可能缺少禁止。不管怎样,我现在很困。也许有人能找到。
相关文章:
- 强制转换为引用类型
- 存储模板类型以强制转换回派生<T>
- 自定义引用类型
- 在C++中,如何在变量中正确存储 BYTE 类型?
- Java 中是否有类似于 C++ 中引用类型"&"的内容?
- 为什么我不能在运算符=中使用引用类型?
- 不存储类类型<>
- 可变参数模板函数参数和引用类型推导
- 隐式可转换参数,但属于引用类型
- 如何告诉自动推断向量<bool>元素的非引用类型
- 为什么"const auto [x, y]"绑定到引用类型时没有按预期运行?
- 引用类型的数据成员提供有关恒常正确性"loophole"
- 为什么引用类型在使用临时对象访问时是左值
- 什么是常量指针常量引用类型的参数?(const X* const & p)
- 在 lambda 中从引用类型捕获的值的类型,不使用通用捕获
- 如何在结构中存储模板类型
- 在闭包中,如何通过存储在内存中的指针或引用类型捕获可变性或用现代函数式语言进行处理?
- 引用类型和存储持续时间
- 我如何设法在标准容器中存储引用类型?
- 引用类型变量初始化和存储