以下代码无法在 gcc 4.8.2 上编译。
问题是此代码将尝试复制构造 std::pair<int, A>由于struct A,这不可能发生缺少复制和移动构造函数。
gcc 在这里失败还是我遗漏了什么?
#include <map>
struct A
{
int bla;
A(int blub):bla(blub){}
A(A&&) = delete;
A(const A&) = delete;
A& operator=(A&&) = delete;
A& operator=(const A&) = delete;
};
int main()
{
std::map<int, A> map;
map.emplace(1, 2); // doesn't work
map.emplace(std::piecewise_construct,
std::forward_as_tuple(1),
std::forward_as_tuple(2)
); // works like a charm
return 0;
}
最佳答案
据我所知,问题不是由 map::emplace 引起的。 , 但由 pair的构造函数:
#include <map>
struct A
{
A(int) {}
A(A&&) = delete;
A(A const&) = delete;
};
int main()
{
std::pair<int, A> x(1, 4); // error
}
据我所知,无论是使用 coliru 的 g++4.8.1 还是 clang++3.5,此代码示例都无法编译,它们都使用 libstdc++。
问题的根源在于,虽然我们可以构造
A t(4);
也就是说,std::is_constructible<A, int>::value == true ,我们不能隐式转换 int到 A [转化]/3
An expression
ecan be implicitly converted to a typeTif and only if the declarationT t=e;is well-formed, for some invented temporary variablet.
注意复制初始化(=)。这会创建一个临时的 A并初始化 t从这个临时的,[dcl.init]/17。这个临时初始化尝试调用 A 的已删除移动 ctor ,这使得转换格式不正确。
因为我们无法从 int 转换到 A ,pair 的构造函数期望被称为被 SFINAE 拒绝。这种行为令人惊讶,N4387 - Improving pair and tuple分析并尝试通过构造构造函数 explicit 来改善这种情况而不是拒绝它。 N4387 在 Lenexa session 上被选为 C++1z。
下面介绍C++11规则。
[pairs.pair]/7-9 中描述了我期望调用的构造函数
template<class U, class V> constexpr pair(U&& x, V&& y);7 Requires:
is_constructible<first_type, U&&>::valueistrueandis_constructible<second_type, V&&>::valueistrue.8 Effects: The constructor initializes first with
std::forward<U>(x)and second withstd::forward<V>(y).9 Remarks: If
Uis not implicitly convertible tofirst_typeorVis not implicitly convertible tosecond_typethis constructor shall not participate in overload resolution.
注意 is_constructible 之间的区别在 Requires 部分中,并且在 Remarks 部分中“不可隐式转换”。满足调用此构造函数的要求,但它可能不参与重载决议(= 必须通过 SFINAE 拒绝)。
因此,重载解析需要选择一个“更差的匹配”,即第二个参数为A const&的匹配。 .临时从 int 创建参数并绑定(bind)到该引用,该引用用于初始化 pair数据成员 (.second)。初始化尝试调用 A 的已删除拷贝 ctor , 并且该对的构造是非良构的。
libstdc++ 有(作为扩展)一些非标准的ctors。在 latest doxygen (以及在 4.8.2 中),pair 的构造函数我预计会被调用(对标准要求的规则感到惊讶)是:
template<class _U1, class _U2,
class = typename enable_if<__and_<is_convertible<_U1, _T1>,
is_convertible<_U2, _T2>
>::value
>::type>
constexpr pair(_U1&& __x, _U2&& __y)
: first(std::forward<_U1>(__x)), second(std::forward<_U2>(__y)) { }
实际上是调用的是非标准的:
// DR 811.
template<class _U1,
class = typename enable_if<is_convertible<_U1, _T1>::value>::type>
constexpr pair(_U1&& __x, const _T2& __y)
: first(std::forward<_U1>(__x)), second(__y) { }
根据标准,程序格式不正确,它不仅仅被这个非标准的ctor拒绝。
最后,这里是 is_constructible 的规范。和 is_convertible .
is_constructible [meta.rel]/4
Given the following function prototype:
template <class T> typename add_rvalue_reference<T>::type create();the predicate condition for a template specialization
is_constructible<T, Args...>shall be satisfied if and only if the following variable definition would be well-formed for some invented variablet:T t(create<Args>()...);[Note: These tokens are never interpreted as a function declaration. — end note] Access checking is performed as if in a context unrelated to
Tand any of theArgs. Only the validity of the immediate context of the variable initialization is considered.
is_convertible [meta.unary.prop]/6:
Given the following function prototype:
template <class T> typename add_rvalue_reference<T>::type create();the predicate condition for a template specialization
is_convertible<From, To>shall be satisfied if and only if the return expression in the following code would be well-formed, including any implicit conversions to the return type of the function:To test() { return create<From>(); }[Note: This requirement gives well defined results for reference types, void types, array types, and function types. — end note] Access checking is performed as if in a context unrelated to
ToandFrom. Only the validity of the immediate context of the expression of the return-statement (including conversions to the return type) is considered.
适合您的类型 A ,
A t(create<int>());
格式正确;然而
A test() {
return create<int>();
}
创建 A 类型的临时并尝试将其移动到返回值(复制初始化)。选择删除的 ctor A(A&&)因此是不正确的。
关于c++ - 为什么我需要在 map::emplace 中为不可复制对象的单个 arg 构造函数使用分段构造?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21405674/
我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div
总的来说,我对ruby还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用
我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看rubyzip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d
类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
很好奇,就使用rubyonrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提
假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于
我正在尝试使用ruby和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
当我使用Bundler时,是否需要在我的Gemfile中将其列为依赖项?毕竟,我的代码中有些地方需要它。例如,当我进行Bundler设置时:require"bundler/setup" 最佳答案 没有。您可以尝试,但首先您必须用鞋带将自己抬离地面。 关于ruby-我需要将Bundler本身添加到Gemfile中吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/4758609/
我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co