根据 C++ 标准,以下程序的预期(如果有)输出是什么:
#include <iostream>
#include <iomanip>
#include <type_traits>
class A {
public:
A() = default;
~A() = default;
A(A const& other) {}
A(A&& other) noexcept {}
A& operator=(A other) noexcept { return *this; }
};
int main() {
std::cout << std::boolalpha
<< std::is_nothrow_copy_assignable<A>::value << "\n"
<< std::is_nothrow_move_assignable<A>::value << "\n";
}
换句话说,类型特征值的评估是否只看赋值运算符的声明,即 noexcept,并因此产生
true
true
或者它是否考虑调用上下文( a 、 b 是 A 的实例)
a = b; // may throw, implicitly calls copy c'tor
a = std::move(b); // noexcept, implicitly calls move c'tor
它是否产生
false
true
实践尝试
使用 Visual Studio 2015 运行代码,Update 3 提供
true
true
而 gcc 6.1 给出了
false
true
谁是对的?
背景
当我们有一个带有抛出复制构造函数(因为资源分配可能会失败)、一个 noexcept 移动构造函数、一个抛出复制赋值和一个 noexcept 移动赋值的资源管理类时,就会出现这种情况。
假设复制和移动分配都可以根据交换 IDOM 有效地实现:
A& operator=(A const& other) {
A(other).swap(*this); // calls the copy c'tor, may throw
return *this;
}
A& operator=(A&& other) noexcept {
A(std::move(other)).swap(*this); // calls noexcept move c'tor
return *this;
}
然后我们可能会考虑将两者压缩成单个按值复制分配
A& operator=(A other) noexcept {
other.swap(*this);
return *this;
}
但是,我们只有在 std::is_nothrow_copy_assignable<A> 时才能安全地执行此操作和 std::is_nothrow_move_assignable<A>提供正确的值(分别为 false 和 true)。否则,依赖于这些类型特征的代码会表现得很糟糕,我们的单个按值赋值将不能正确地替代两个单独的赋值运算符。
最佳答案
is_nothrow_copy_assignable的定义在 [meta.unary.prop] 中:
For a referenceable type
T, the same result asis_nothrow_assignable_v<T&, const T&>, otherwisefalse.
好的,A是可引用的(意思是 A& 是有效的)。所以我们进入is_nothrow_assignable :
is_assignable_v<T, U>istrueand the assignment is known not to throw any exceptions (5.3.7).
is_assignable_v<A, A const&>绝对是true , 所以我们满足第一部分。众所周知不抛出任何异常是什么意思?根据 [expr.unary.noexcept]:
The
noexceptoperator determines whether the evaluation of its operand, which is an unevaluated operand (Clause 5), can throw an exception (15.1). [...] The result of thenoexceptoperator istrueif the set of potential exceptions of the expression (15.4) is empty, and false otherwise.
在 [except.spec] 中:
The exception-specification
noexceptornoexcept(constant-expression), where the constant-expression yieldstrue, denotes an exception specification that is the empty set. The exception-specificationnoexcept(constant-expression), where the constant-expression yieldsfalse, or the absence of an exception-specification in a function declarator other than that for a destructor (12.4) or a deallocation function (3.7.4.2) denotes an exception specification that is the set of all types.
和:
The set of potential exceptions of an expression e is empty if e is a core constant expression (5.20). Otherwise, it is the union of the sets of potential exceptions of the immediate sub-expressions of e, including default argument expressions used in a function call, combined with a set S defined by the form of e, as follows: [...]
— If e implicitly invokes one or more functions (such as an overloaded operator, an allocation function in a new-expression, or a destructor if e is a full-expression (1.9)), S is the union of:
— the sets of types in the exception specifications of all such functions, and
— if e is a new-expression [...]
现在,一个 A 的赋值来自 A const&包括两个步骤:
A的拷贝构造函数A 的复制赋值运算符| 异常规范是这两个函数的所有异常规范的 union ,它是所有类型的集合——因为复制构造函数根本没有异常规范。
因此,is_nothrow_copy_assignable_v<A>应该是 false . gcc 是正确的。
关于c++ - 对于具有抛出复制构造函数和 noexcept 按值复制赋值的类,is_nothrow_copy_assignable 的值是多少?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42034848/
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
通过rubykoans.com,我在about_array_assignment.rb中遇到了这两段代码你怎么知道第一个是非并行赋值,第二个是一个变量的并行赋值?在我看来,除了命名差异之外,代码几乎完全相同。4deftest_non_parallel_assignment5names=["John","Smith"]6assert_equal["John","Smith"],names7end45deftest_parallel_assignment_with_one_variable46first_name,=["John","Smith"]47assert_equal'John
这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下
给定以下方法:defsome_method:valueend以下语句按我的预期工作:some_method||:other#=>:valuex=some_method||:other#=>:value但是下面语句的行为让我感到困惑:some_method=some_method||:other#=>:other它按预期创建了一个名为some_method的局部变量,随后对some_method的调用返回该局部变量的值。但为什么它分配:other而不是:value呢?我知道这可能不是一件明智的事情,并且可以看出它可能有多么模棱两可,但我认为应该在考虑作业之前评估作业的右侧...我已经在R
如何将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.你能做的最好的事情是:
我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我
我正在尝试使用“updated_at”字段的日期时间范围查询数据库。前端在JSON数组中发送查询:["2015-09-0100:00:00","2015-10-0223:00:00"]在RailsController中,我使用以下方法将两个字符串解析为DateTime:start_date=DateTime.parse(params[:date_range_arr][0])end_date=DateTime.parse(params[:date_range_arr][1])#...@events=@events.where('updated_atBETWEEN?AND?,start_d
我目前正在尝试学习RubyonRails和测试框架RSpec。assigns在此RSpec测试中做什么?describe"GETindex"doit"assignsallmymodelas@mymodel"domymodel=Factory(:mymodel)get:indexassigns(:mymodels).shouldeq([mymodel])endend 最佳答案 assigns只是检查您在Controller中设置的实例变量的值。这里检查@mymodels。 关于ruby-o
我遇到了这个奇怪的错误.../Users/gideon/Documents/ca_ruby/rubytactoe/lib/player.rb:13:in`gets':Isadirectory-spec(Errno::EISDIR)player_spec.rb:require_relative'../spec_helper'#theuniverseisvastandinfinite...itcontainsagame....butnoplayersdescribe"tictactoegame"docontext"theplayerclass"doit"musthaveahumanplay
我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“