在Ruby中,我们使用=运算符为对象赋值.
将此与隐式类型相结合,我们经常遇到这样的情况:
myVar= :asymbol
Run Code Online (Sandbox Code Playgroud)
上面的行都创建了一个新的符号对象,并将该对象绑定到变量名称myVar.
从语义上讲,这是怎么做到的?
我已经在脑子里敲了一下,=操作符不是内置在解释器中的魔法语法,但实际上只是该object.=(value)方法的语法糖.
考虑到这一点,我最好的猜测是,该解释认为我们正在试图将值赋给一个未定义的变量名的时候,它首先会创建一些特殊类型的新对象,像undefined或null什么的,然后传递:=消息到有效载荷的对象是我们试图分配的值.
但是,调用.class一个未实例化的对象只会抛出一个异常,因为Ruby认为我们正在尝试调用一个方法(其名称是您尝试生成的变量的名称)self
> obj.class
> NameError: undefined variable or method 'obj' for main:Object
Run Code Online (Sandbox Code Playgroud)
所以,据我所知,我无法通过实验来解决这个问题.
边注:
在符号赋值的情况下,我相信分配的值(AKA实例化对象的object_id方法返回的值,AKA unsigned long VALUE在C级别上的变量的值)是一个数字,表示某个表中的偏移量(我相信这个Ruby是如何实现符号对象的"直接价值"的.
在其他情况下,该值可以是对象本身的直接编码,或者意图在参考a时强制转换为指针的值struct.
无论如何,Ruby代表对象的方式以及我们最终是否分配引用或对象本身并不是我在这里要求的.
附加问题:
=继承自哪个类的方法?我在Object或BasicObject的规范中找不到它.
这个讨论出现在之前的问题中,我很想知道两者之间的区别.举例说明会很好.
我在接受采访时被问到这个问题,我无法回答这个问题.
更具体地说,赋值运算符所属的类如下所示:
class A {
private:
B* pb;
C* pc;
....
public:
....
}
Run Code Online (Sandbox Code Playgroud)
如何为此类实现原子(线程安全)和异常安全的深层复制赋值运算符?
在以下代码中:
int c;
while((c=10)>0)
Run Code Online (Sandbox Code Playgroud)
什么是c = 10评价什么?是1表示值10成功分配给变量c,还是10?为什么?
我对c ++隐式复制构造函数的理解类似于
T(T const& x) :
base1(x), base2(x) ... ,
var1(x.var1), var2(x.var2)...
{}
Run Code Online (Sandbox Code Playgroud)
移动构造函数,复制和移动赋值也遵循类似的模式.
为什么没有定义类似于以下内容?
T(T const& x) :
base1(static_cast<base1 const&>(x)),
base2(static_cast<base2 const&>(x)) ... ,
var1(x.var1), var2(x.var2)...
{}
Run Code Online (Sandbox Code Playgroud)
例
我有一个类具有隐式复制/移动构造函数/赋值运算符,以及一些转换构造函数.我把工作委托给了一些实现类.
class common_work //common implementation of many work like classes
{
common_work(common_work const&) = default;
common_work(common_work&&) = default;// ... implicit constructors work for me.
//a forwarding constructor which can take many work like objects
template<class T, enable_if<work_like<T> > >
common_work(T&& x) { ... }
};
class work1 //one of the implementation …Run Code Online (Sandbox Code Playgroud) c++ constructor assignment-operator perfect-forwarding c++11
看起来std::tuple包含一个或多个引用在构造和赋值方面具有意外行为(尤其是复制/移动构造和复制/移动分配).它与两者的行为std::reference_wrapper(更改引用的对象)和具有成员引用变量的结构(赋值运算符已删除)不同.它允许方便的std::tiepython像多个返回值,但它也允许明显不正确的代码,如下所示(链接在这里):
#include <tuple>
int main()
{
std::tuple<int&> x{std::forward_as_tuple(9)}; // OK - doesn't seem like it should be
std::forward_as_tuple(5) = x; // OK - doesn't seem like it should be
// std::get<0>(std::forward_as_tuple(5)) = std::get<0>(x); // ERROR - and should be
return 0;
}
Run Code Online (Sandbox Code Playgroud)
该标准似乎要求或强烈暗示20.4.2.2.9最新工作草案的副本(ish)分配部分中的此行为(Ti&将折叠为左值ref):
template <class... UTypes> tuple& operator=(const tuple<UTypes...>& u);9 要求:
sizeof...(Types) == sizeof...(UTypes)并且is_assignable<Ti&, const Ui&>::value对所有人都是如此i.10 效果:将u的每个元素分配给*this的相应元素.
11 返回:*this …
斯卡拉有时候只是脱毒
a += b
Run Code Online (Sandbox Code Playgroud)
至
a = a + b
Run Code Online (Sandbox Code Playgroud)
但不总是.例如,一些可变集合定义了一个+=方法,而不是它变成了一个方法
a.+=(b)
Run Code Online (Sandbox Code Playgroud)
这是这种行为吗?
+=方法a?(包括有这种行为的其他例子吗?)相关的例子
改编自Scala中的编程
var s = Set("a", "b")
s += "c"
Run Code Online (Sandbox Code Playgroud)
在这种情况下,第二行代码
s += "c"基本上是简写:
s = s + "c"
Run Code Online (Sandbox Code Playgroud) 这个问题旨在成为整数和指针问题之间所有初始化/分配的常见问题解答条目。
我想编写代码,将指针设置为特定的内存地址,例如0x12345678. 但是当用 gcc 编译器编译这段代码时,我得到“初始化使指针从整数而不进行强制转换”警告/错误:
int* p = 0x12345678;
Run Code Online (Sandbox Code Playgroud)
类似地,这段代码给出了“初始化从指针生成整数而不进行强制转换”:
int* p = ...;
int i = p;
Run Code Online (Sandbox Code Playgroud)
如果我在变量声明行之外做同样的事情,消息是一样的,但说的是“赋值”而不是“初始化”:
p = 0x12345678; // "assignment makes pointer from integer without a cast"
i = p; // "assignment makes integer from pointer without a cast"
Run Code Online (Sandbox Code Playgroud)
使用其他流行编译器的测试也会给出错误/警告消息:
int不能用于初始化类型的实体int*”int*在间接级别上与int”不同。问题:上面的例子是有效的 C 吗?
还有一个后续问题:
这不会给出任何警告/错误:
int* p = 0;
Run Code Online (Sandbox Code Playgroud)
为什么不?
在C ++中,表达式left() = right()求值
right()left()按此顺序。该right()先行,如已经讨论这里。
我想不出right()先走的理由。你是否可以?我认为这是有原因的。否则,该标准几乎不会说出它的意思,而是要考虑:right()将返回一些结果。在机器代码级别上,CPU是否不需要在将结果right()返回之前就知道将结果放回何处right()?
如果您碰巧知道标准委员会在想什么(因为您在房间里或已经阅读备忘录),那就太好了:我想阅读您的答案。但是,我的实际问题较为温和。我只想知道是否存在合理的原因,以及该原因可能是什么。
我了解到我们可以为 C++ 中的类提供转换运算符。所以我预计对于以下程序,c=1;会使用转换运算符int()。但令我惊讶的是;但这并没有发生,我们得到一个编译器错误,指出
error: no match for 'operator=' (operand types are 'C' and 'int')。
所以我想知道为什么这里不使用转换运算符。
struct C {
explicit C(int);
operator int&();
};
int main() {
C c({});
c = 1; //this gives error. Why the conversion operator int&() is not used here?
}
Run Code Online (Sandbox Code Playgroud)
请注意,我知道如果我explicit从构造函数中删除关键字就可以解决该错误。但我的问题是为什么不使用转换运算符。
我认为既然我们的类有一个转换运算符,那么可以将类对象转换为 anint以便可以将其分配给。
c++ explicit type-conversion assignment-operator language-lawyer