经常看到使用 STL 算法的示例用列表初始化容器来说明,例如:
std::vector< int > v{1, 2, 3, 4};
但是当这种方法用于(重量级)类(不像ints)时,它意味着过度的复制操作,即使它们被传递给右值(移至),因为上面示例中使用的std::initializer_list 仅提供const_iterator。
为了解决这个问题,我使用了以下 (C++17) 方法:
template< typename Container, typename ...Args >
Container make_container(Args &&... args)
{
Container c;
(c.push_back(std::forward< Args >(args)), ...);
// ((c.insert(std::cend(c), std::forward< Args >(args)), void(0)), ...); // more generic approach
return c;
}
auto u = make_container< std::vector< A > >(A{}, A{}, A{});
但是当我执行以下操作时,它变得不令人满意:
A a;
B b;
using P = std::pair< A, B >;
auto v = make_container< std::vector< P > >(P{a, b}, P{std::move(a), std::move(b)});
在这里,我想通过移动操作替换复制操作来为每个值保存一个复制操作(假设移动 A 或 B 更便宜然后复制),但通常不能,因为函数参数的求值顺序在 C++ 中未定义。我目前的解决方案是:
template< Container >
struct make_container
{
template< typename ...Args >
make_container(Args &&... args)
{
(c.push_back(std::forward< Args >(args)), ...);
}
operator Container () && { return std::move(c); }
private :
Container c;
};
A a; B b;
using P = std::pair< A, B >;
using V = std::vector< P >;
V w = make_container< V >{P{a, b}, P{std::move(a), std::move(b)}};
在构造函数体中做一些重要的工作通常被认为是一种不好的做法,但在这里我集中使用了 list-initialization 的特性——事实上它被严格保留- 向右排序。
从某些特定的角度来看,这是完全错误的方法吗?除了上述方法之外,这种方法还有哪些缺点?当前(在 C++11、C++14、C++1z 中)是否有另一种技术可以实现可预测的函数参数求值顺序?
最佳答案
有一个更好的解决方案:
template<class Container, std::size_t N>
inline Container make_container(typename Container::value_type (&&a)[N])
{
return Container(std::make_move_iterator(std::begin(a)), std::make_move_iterator(std::end(a)));
}
你可以这样使用它:
make_container<std::vector<A>>({A(1), A(2)})
它不需要可变参数模板,它仍然是列表初始化但不是 std::initializer_list,这次它是一个普通数组,因此您可以从中移动元素。
与您的原始解决方案相比的显着优势:
Container的ctor可以提供更好的性能(例如std::vector可以保留所有需要的内存)关于c++ - 利用容器的移动语义和元素初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36077772/
在我的gem中,我需要yaml并且在我的本地计算机上运行良好。但是在将我的gem推送到rubygems.org之后,当我尝试使用我的gem时,我收到一条错误消息=>"uninitializedconstantPsych::Syck(NameError)"谁能帮我解决这个问题?附言RubyVersion=>ruby1.9.2,GemVersion=>1.6.2,Bundlerversion=>1.0.15 最佳答案 经过几个小时的研究,我发现=>“YAML使用未维护的Syck库,而Psych使用现代的LibYAML”因此,为了解决
我的代码目前看起来像这样numbers=[1,2,3,4,5]defpop_threepop=[]3.times{pop有没有办法在一行中完成pop_three方法中的内容?我基本上想做类似numbers.slice(0,3)的事情,但要删除切片中的数组项。嗯...嗯,我想我刚刚意识到我可以试试slice! 最佳答案 是numbers.pop(3)或者numbers.shift(3)如果你想要另一边。 关于ruby-多次弹出/移动ruby数组,我们在StackOverflow上找到一
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我在Rails工作并有以下类(class):classPlayer当我运行时bundleexecrailsconsole然后尝试:a=Player.new("me",5.0,"UCLA")我回来了:=>#我不知道为什么Player对象不会在这里初始化。关于可能导致此问题的操作/解释的任何建议?谢谢,马里奥格 最佳答案 havenoideawhythePlayerobjectwouldn'tbeinitializedhere它没有初始化很简单,因为你还没有初始化它!您已经覆盖了ActiveRecord::Base初始化方法,但您没有调
我有用于控制用户任务的Rails5API项目,我有以下错误,但并非总是针对相同的Controller和路由。ActionController::RoutingError:uninitializedconstantApi::V1::ApiController我向您描述了一些我的项目,以更详细地解释错误。应用结构路线scopemodule:'api'donamespace:v1do#=>Loginroutesscopemodule:'login'domatch'login',to:'sessions#login',as:'login',via::postend#=>Teamroutessc
当我在我的Rails应用程序根目录中运行rakedoc:app时,API文档是使用/doc/README_FOR_APP作为主页生成的。我想向该文件添加.rdoc扩展名,以便它在GitHub上正确呈现。更好的是,我想将它移动到应用程序根目录(/README.rdoc)。有没有办法通过修改包含的rake/rdoctask任务在我的Rakefile中执行此操作?是否有某个地方可以查找可以修改的主页文件的名称?还是我必须编写一个新的Rake任务?额外的问题:Rails应用程序的两个单独文件/README和/doc/README_FOR_APP背后的逻辑是什么?为什么不只有一个?
我正在阅读一本关于Ruby的书,作者在编写类初始化定义时使用的形式与他在本书前几节中使用的形式略有不同。它看起来像这样:classTicketattr_accessor:venue,:datedefinitialize(venue,date)self.venue=venueself.date=dateendend在本书的前几节中,它的定义如下:classTicketattr_accessor:venue,:datedefinitialize(venue,date)@venue=venue@date=dateendend在第一个示例中使用setter方法与在第二个示例中使用实例变量之间是
查看我的Ruby代码:h=Hash.new([])h[0]=:word1h[1]=h[1]输出是:Hash={0=>:word1,1=>[:word2,:word3],2=>[:word2,:word3]}我希望有Hash={0=>:word1,1=>[:word2],2=>[:word3]}为什么要附加第二个哈希元素(数组)?如何将新数组元素附加到第三个哈希元素? 最佳答案 如果您提供单个值作为Hash.new的参数(例如Hash.new([]),完全相同的对象将用作每个缺失键的默认值。这就是您所拥有的,那是你不想要的。您可以改用
如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:
本文主要介绍在使用Selenium进行自动化测试或者任务时,对于使用了iframe的页面,如何定位iframe中的元素文章目录场景描述解决方案具体代码场景描述当我们在使用Selenium进行自动化测试的时候,可能会遇到一些界面或者窗体是使用HTML的iframe标签进行承载的。对于iframe中的标签,如果直接查找是无法找到的,会抛出没有找到元素的异常。比如近在咫尺的例子就是,CSDN的登录窗体就是使用的iframe,大家可以尝试通过F12开发者模式查看到的tag_name,class_name,id或者xpath来定位中的页面元素,会抛出NoSuchElementException异常。解决