我需要一个 API 尽可能接近 std::vector 的容器类(除非没有重新分配),但可以指定其元素的存储(而不是其成员变量,如大小)从现有缓冲区分配,这样我就可以将所有 vector 的元素保存在一个连续的缓冲区中。也就是说,一个 vector 的 .end() 指向缓冲区中与下一个 vector 的 .front() 相同的元素。
我不知道我是否可以简单地使用带有 std::vector 的自定义分配器,因为我找不到关于它是否为整个类分配存储的信息,包括大小和指针数据成员(在这种情况下我不能使用这种方法),或者只是它包含的数据元素(在这种情况下我可以使用它)。
我只需要分配一次实例的存储空间,因此重新分配没有问题。我在这里发帖是为了看看是否已经发布了这样的容器,而不是从头开始使用迭代器等重新实现大部分 std vector 接口(interface)。
更新:我取消选中发布的答案,因为它在 Visual C++ 2012 的 Debug模式下不起作用。T = float 的示例:
template<class T>
inline typename ContigAlloc<T>::pointer ContigAlloc<T>::allocate(std::size_t n)
{
std::cout << "Alloc " << n << "; type match: " << std::boolalpha << std::is_same<T, float>::value << std::endl;
return reinterpret_cast<T *>(_buff.alloc(T * sizeof(n)));
}
template<class T>
inline void ContigAlloc<T>::deallocate(T *p, std::size_t n) // TODO: noexcept when VC++2013
{
std::cout << "Deall " << n << "; type match: " << std::boolalpha << std::is_same<T, float>::value << std::endl;
_buff.dealloc(p, T * sizeof(n));
}
测试:
std::vector<float, ContigAlloc<float>> vec;
vec.push_back(1.1f);
vec.push_back(1.9f);
发布构建的结果很好:
Alloc 1; type match: true
Alloc 2; type match: true
Deall 1; type match: true
Deall 2; type match: true
调试构建的结果不很好:
Alloc 1; type match: false
Alloc 1; type match: true
Alloc 2; type match: true
Deall 1; type match: true
Deall 2; type match: true
Deall 1; type match: false
在第一次调用allocate()时,T = _Container_proxy
最佳答案
分配器仅用于为元素分配存储空间。为此,您可以使用自定义分配器。
Jon 在下面的评论中纠正了我的错误。
我认为可以实现一个符合规范的vector,这样它就可以将除指针之外的所有内容都存储在堆上。堆上的东西要么是 3 个指针,加上分配器(如果分配器没有优化掉),要么是 1 个指针、大小和容量(以及可能优化掉的分配器)。
在实践中,std::vector 的每一个实现都曾以任何类型的数量交付,包括:
已将所有支持成员放置在 vector 类本身中,并且仅使用分配器来分配数据。而且似乎没有什么动力去做其他事情。
所以这是一个事实上的标准,而不是官方标准。有了上面的历史,这是一个非常安全的。
请注意,不能对 string 做出相同的声明,它在概念上具有相同的布局。 string 的 C++11 实现通常会使用“短字符串”优化,其中分配器根本不用于“短”字符串,而是将值嵌入到字符串类中。 23.2.1 一般容器要求 [container.requirements.general]/10:
vector 进行这种优化
(Unless otherwise specified) no swap() function invalidates any references, pointers, or iterators referring to the elements of the containers being swapped.
关于c++ - 可以具有存储相互连续的实例的类似 vector 的容器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23962485/
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..
我试图获取一个长度在1到10之间的字符串,并输出将字符串分解为大小为1、2或3的连续子字符串的所有可能方式。例如:输入:123456将整数分割成单个字符,然后继续查找组合。该代码将返回以下所有数组。[1,2,3,4,5,6][12,3,4,5,6][1,23,4,5,6][1,2,34,5,6][1,2,3,45,6][1,2,3,4,56][12,34,5,6][12,3,45,6][12,3,4,56][1,23,45,6][1,2,34,56][1,23,4,56][12,34,56][123,4,5,6][1,234,5,6][1,2,345,6][1,2,3,456][123
我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i
使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta
查看Ruby的CSV库的文档,我非常确定这是可能且简单的。我只需要使用Ruby删除CSV文件的前三列,但我没有成功运行它。 最佳答案 csv_table=CSV.read(file_path_in,:headers=>true)csv_table.delete("header_name")csv_table.to_csv#=>ThenewCSVinstringformat检查CSV::Table文档:http://ruby-doc.org/stdlib-1.9.2/libdoc/csv/rdoc/CSV/Table.html
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我正在查看instance_variable_set的文档并看到给出的示例代码是这样做的:obj.instance_variable_set(:@instnc_var,"valuefortheinstancevariable")然后允许您在类的任何实例方法中以@instnc_var的形式访问该变量。我想知道为什么在@instnc_var之前需要一个冒号:。冒号有什么作用? 最佳答案 我的第一直觉是告诉你不要使用instance_variable_set除非你真的知道你用它做什么。它本质上是一种元编程工具或绕过实例变量可见性的黑客攻击
在我的应用程序中,我需要能够找到所有数字子字符串,然后扫描每个子字符串,找到第一个匹配范围(例如5到15之间)的子字符串,并将该实例替换为另一个字符串“X”。我的测试字符串s="1foo100bar10gee1"我的初始模式是1个或多个数字的任何字符串,例如,re=Regexp.new(/\d+/)matches=s.scan(re)给出["1","100","10","1"]如果我想用“X”替换第N个匹配项,并且只替换第N个匹配项,我该怎么做?例如,如果我想替换第三个匹配项“10”(匹配项[2]),我不能只说s[matches[2]]="X"因为它做了两次替换“1fooX0barXg
我发现ActiveRecord::Base.transaction在复杂方法中非常有效。我想知道是否可以在如下事务中从AWSS3上传/删除文件:S3Object.transactiondo#writeintofiles#raiseanexceptionend引发异常后,每个操作都应在S3上回滚。S3Object这可能吗?? 最佳答案 虽然S3API具有批量删除功能,但它不支持事务,因为每个删除操作都可以独立于其他操作成功/失败。该API不提供任何批量上传功能(通过PUT或POST),因此每个上传操作都是通过一个独立的API调用完成的