以下代码在gcc 4.8.1上编译没有问题:
#include <utility>
struct foo
{
};
int main()
{
foo bar;
foo() = bar;
foo() = std::move( bar );
}
Run Code Online (Sandbox Code Playgroud)
似乎隐式生成的赋值运算符foo不是&ref-qualified,因此可以在rvalues上调用.根据标准,这是正确的吗?如果是这样,有什么理由不要求隐式生成的赋值运算符被重新&限定?
为什么标准不要求生成以下内容?
struct foo
{
foo & operator=( foo const & ) &;
foo & operator=( foo && ) &;
};
Run Code Online (Sandbox Code Playgroud) 所以我有一个提供字符串类型的现有库.
它隐式转换为C样式字符串,如下所示:
struct TypeIDoNotOwn {
TypeIDoNotOwn() {}
TypeIDoNotOwn(TypeIDoNotOwn const&) {}
TypeIDoNotOwn(char const*) {}
TypeIDoNotOwn& operator=(TypeIDoNotOwn const&) {return *this;}
TypeIDoNotOwn& operator=(char const*) {return *this;}
operator char const*() const {return nullptr;}
};
Run Code Online (Sandbox Code Playgroud)
它有其他方法,但我不认为它们很重要.这些方法有机构,但我的问题不涉及它们,所以我把它们剔除了.
我想要做的是创建一个可以与上述类型相对可互换使用的新类型,并使用"raw string constants".我希望能够获取一个实例TypeIDoNotOwn,并替换它TypeIDoOwn,并编译代码.
举个例子,这套操作:
void test( TypeIDoNotOwn const& x ) {}
int main() {
TypeIOwn a = TypeIDoNotOwn();
TypeIDoNotOwn b;
a = b;
b = a;
TypeIOwn c = "hello";
TypeIDoNotOwn d = c;
a = "world";
d = "world";
char const* e …Run Code Online (Sandbox Code Playgroud) 我知道列表赋值会使其左侧变平:
\nmy ($a, $b, $c);\n($a, ($b, $c)) = (0, (1.0, 1.1), 2);\nsay "\\$a: $a"; # OUTPUT: \xc2\xab$a: 0\xc2\xbb\nsay "\\$b: $b"; # OUTPUT: \xc2\xab$b: 1 1.1\xc2\xbb <-- $b is *not* 1\nsay "\\$c: $c"; # OUTPUT: \xc2\xab$c: 2\xc2\xbb <-- $c is *not* 1.1\nRun Code Online (Sandbox Code Playgroud)\n我也明白我们可以用来:($a, ($b, $c)) := (0, (1.0, 1.1))获得非扁平化行为。
我不明白的是为什么在列表分配期间左侧被展平。这是两个问题:首先,这种扁平化行为如何与语言的其余部分相适应?其次,自动展平是否允许任何在左侧不展平时不可能出现的行为?
\n关于第一个问题,我知道 Raku 历史上有很多自动扁平化行为。在Great List Refactor之前,像这样的表达式my @a = 1, (2, 3), 4会自动展平其右侧,从而产生 Array [1, 2, 3, 4];同样,map许多其他迭代结构也会使他们的论点变得扁平化。不过,在 …
destructuring variable-assignment flatten assignment-operator raku
我可以做点什么
def f(): Tuple2[String, Long] = ...
val (a, b) = f()
Run Code Online (Sandbox Code Playgroud)
如果变量已经存在怎么办?我在过滤器上运行相同的数据集,我不想链接它们(长名称等).这是我尝试过的,但它抱怨期待; 而不是在最后一行=:
var a = ...initialization for this data
var b = ...some other init
(a, b) = g(a, b) // error: expected ';' but found '='
Run Code Online (Sandbox Code Playgroud)
有没有办法避免中间元组?
我有一个类似于以下的类定义:
class UUID
{
public:
// Using implicit copy assignment operator
private:
unsigned char buffer[16];
};
Run Code Online (Sandbox Code Playgroud)
我刚刚对我进行了单元测试失败,验证了副本分配是否正常工作.令我惊讶的是,buffer []数组中间的一个字节被错误地复制了.
我的理解是,默认的复制赋值操作符执行成员复制,而数组成员(不是指向数组的成员)则需要执行元素的元素复制.我错了吗?
我在这里的直觉是,我被一个悬挂在指针中间的指针咬了一下.但是,当我将这些物体的矢量复制到另一个矢量时,我可以重复地看到这一点.
有人想告诉我哪里出错了吗?
编辑:
为了扩展这一点,该类不是POD类型 - 它派生自一些抽象基类,因此具有虚拟析构函数.但是,数组是唯一的数据成员,单元测试中的用法是这样的:
const int n = 100;
std::vector<UUID> src, dst;
src.reserve(n);
dst.resize(n);
for (int i = 0; i < n; ++i) {
UUID id;
src.push_back(id);
}
for (int i = 0; i < n; ++i) {
dst[i] = src[i];
}
bool good = true;
for (int i = 0; i < n; ++i) {
const bool thisGood …Run Code Online (Sandbox Code Playgroud) 这是我用来索引令牌的常用模式:检查令牌是否在地图中,如果没有,则将其添加到地图中,分配地图的大小.
在C++中执行此操作时,它会在分配之前意外地增加映射的大小:
#include <cstdio>
#include <map>
using namespace std;
int main() {
map<char, int> m;
printf("Size before adding: %d\n", m.size());
m['A'] = m.size();
printf("Size after adding: %d\n", m.size());
printf("What was added: %d\n", m['A']);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
打印出:
Size before adding: 0
Size after adding: 1
What was added: 1
Run Code Online (Sandbox Code Playgroud)
我理解它的方式,它应该评估右侧,即零,然后将其传递给将"A"和零置于地图中的函数.但它似乎是在开始分配之后对其进行评估,这没有任何意义.
在分配操作之前,不应评估右侧吗?
当我偶然发现这个片段时,我只是在看functools.lru_cache的实现:
root = [] # root of the circular doubly linked list
root[:] = [root, root, None, None] # initialize by pointing to self
Run Code Online (Sandbox Code Playgroud)
我熟悉循环和双向链表.我也知道new_list = my_list[:]创建了my_list的副本.在查找切片分配或圆形双向链表的其他实现时,我找不到有关此特定语法的任何进一步信息.
问题:
some_list[:] =
some_iterable(没有自引用)是否有不同的常见用例?假设sizeof( int ) == sizeof( float ),并且我有以下代码片段:
union U{
int i;
float f;
};
U u1, u2;
u1.i = 1; //i is the active member of u1
u2.f = 1.0f; //f is the active member of u2
u1 = u2;
Run Code Online (Sandbox Code Playgroud)
我的问题:
u1分配后的活跃成员是什么?为什么?u1赋值后可以读取 的哪个成员而不会导致 UB,为什么?我们有这个代码:
Test1 t1;
Test2 t2;
t1 = t2;
Run Code Online (Sandbox Code Playgroud)
我相信有三种(或更多?)方法如何实施 t1 = t2
Test1Test2Test1(const Test2&)转换构造函数根据我的GCC测试,这是使用的优先级:
请帮我理解为什么这个优先.
我使用此代码进行测试(取消注释某些行以试用)
struct Test2;
struct Test1 {
Test1() { }
Test1(const Test2& t) { puts("const constructor wins"); }
// Test1(Test2& t) { puts("constructor wins"); }
// Test1& operator=(Test2& t) { puts("assign wins"); }
};
struct Test2 {
Test2() { }
// operator Test1() const { puts("const cast wins"); return Test1(); }
// operator Test1() { puts("cast …Run Code Online (Sandbox Code Playgroud) 我总是新手到C++世界(也是C).而且不知道它的所有细节.但有一件事让我感到困扰.它是如下构造:
while (a=b) {...}.我理解这种魔法是有效的,因为C和C++中的赋值运算符返回了一些东西.所以问题是:它返回了什么?这是一个记录在案的东西吗?它在C和C++中的作用是否相同.关于赋值运算符及其在C和C++中的实现的低级细节(如果存在差异)将非常感激!
我希望这个问题不会被关闭,因为从低层次的角度来看,我无法找到关于这个主题的全面解释和好材料.