小编led*_*ter的帖子

值初始化和非POD类型

一个小时前我在这里发了一个答案,根据我的说法是正确的.然而我的回答却被Martin B贬低了.他说

你很幸运,并且因为我所处的内存恰好是零初始化而得到了零.标准不保证这一点.

然而读迈克尔·伯尔的回答后,这里并尝试下面的示例代码

1)

#include <cassert>

struct B { ~B(); int m; };

int main()
{
   B * b = new B();
   assert(b->m == 0);
}
Run Code Online (Sandbox Code Playgroud)

我在MSVC++ 2010上遇到调试错误.

我有一个类似的错误,当我尝试下面的代码[我的答案在这里 ]在MSVC++ 2010

2)

#include <cassert>
struct Struct {
    std::string String;
    int Int;
    bool k;
    // add add add
};

struct InStruct : Struct
{
   InStruct() : Struct() {}
};

int main()
{
   InStruct i;
   assert(i.k == 0);
}
Run Code Online (Sandbox Code Playgroud)

既没有(1)也没有(2)给gcc/Clang这样的错误让我想到MSVC++ …

c++ initialization visual-c++ value-initialization

17
推荐指数
2
解决办法
4884
查看次数

返回对特定大小的数组的引用,而不显式声明返回类型的大小

我有以下功能:

... getX()
{
    static int x[] = {1, 2, 3};
    return x;
}
Run Code Online (Sandbox Code Playgroud)

我想要它的返回类型,int(&)[3]但不要明确指定大小(3).

我怎么做?

(请不要问我为什么要那样.)

UPD

嗯,好的,我需要将结果传递给模板函数int(&x)[N]作为参数(我不想将大小明确地传递给该模板函数),所以我看不到返回一对的解决方案如何工作...

c++ return-type c++11 c++14

15
推荐指数
1
解决办法
1007
查看次数

Python 协程是无堆栈的还是有堆栈的?

关于 Python 协程(我主要是指async/await)是无堆栈的还是有堆栈的,我看到了相互矛盾的观点。

一些消息来源称它们是堆栈的:

虽然其他人似乎暗示它们是无堆栈的,例如https://gamelisp.rs/reference/coroutines.html

GameLisp 的协程遵循 Rust、Python、C# 和 C++ 设置的模型。我们的协程是“无堆栈的”

总的来说,我的理解始终是,任何有意义的 async/await 实现都意味着无堆栈协程,而堆栈协程基本上是纤程(用户空间线程,通常或多或少地协作切换),例如 goroutine、Boost.Coroutine,显然是 Lua 中的协程等。

我的理解正确吗?或者 Python 协程在某种程度上与 C++ 中的协程有根本的不同,并且是堆栈式的?或者上述来源的作者是否有不同的意思?

python coroutine python-asyncio

14
推荐指数
1
解决办法
1515
查看次数

为什么复制扣除候选人需要作为单独的扣除指南?

template <typename T> struct A {
    A(T);
    A(const A&);
};

int main()
{
    A x(42); // #1
    A y = x; // #2
}
Run Code Online (Sandbox Code Playgroud)

据我了解,T#1将使用第一个ctor生成的隐式演绎指南推导出.然后x将使用该ctor初始化.

但是对于#2,T将使用复制演绎候选人推断(根据我的理解,这是演绎指南的特定情况)(然后y将使用第二个ctor初始化).

为什么不能T使用复制版本生成的(隐含)演绎指南来推导#2?

我想我只是不明白复制演绎候选人的一般目的.

c++ templates template-argument-deduction argument-deduction c++17

13
推荐指数
1
解决办法
223
查看次数

"复制初始化上下文中的默认初始化"在C++中意味着什么?

例如,我想我理解直接初始化(vs copy-)的上下文中的列表初始化 - 基本上是int x{}vs.int x = {}

但是在cppreference上我发现了这个:

当类类型的对象从相同或派生类类型的对象进行复制初始化,或者在复制初始化上下文中进行默认初始化时,候选函数都是转换正在初始化的类的构造函数.参数列表是初始化程序的表达式.

我想我明白为什么候选人为第一种情况转换构造函数,但不是第二种情况.我的意思是,我不能写出类似的内容MyClass x = MyClass,并且= MyClass()会进行值初始化,并且= MyClass(args...)会直接启动.

即使存在这样的构造,我也不明白为什么临时MyClass对象'构造'应该特别包括所有转换构造函数.

(x正如我所看到的那样,并不是在这里讨论的东西,因为它绝对是复制构造的,而不是默认构造的.)

所以我想我对这里的条款感到困惑.

c++ overloading initialization c++14 c++17

11
推荐指数
1
解决办法
245
查看次数

xvalues 与 prvalues:身份属性添加了什么

我对这个问题的广泛性感到抱歉,只是所有这些细节都是紧密相连的。

我一直在尝试理解两个特定值类别 - xvalues 和 prvalues 之间的区别,但我仍然感到困惑。

不管怎样,我试图为自己开发的“同一性”概念的心智模型是,应该保证具有同一性的表达式驻留在实际程序的数据存储器中。

由于这个原因,字符串文字是左值,它们保证在整个程序运行期间驻留在内存中,而数字文字是纯右值,并且可以假设存储在直接汇编中。

这似乎同样适用于std::move纯纯右值文字,即,在调用时,fun(1)我们只会在被调用者框架中获得参数左值,但在调用时,fun(std::move(1))左值的 xvalue“种类”必须保留在调用者框架中。

然而,这种心理模型至少不适用于临时对象,据我所知,临时对象应该始终在实际内存中创建(例如,如果像使用纯右值参数那样调用fun(MyClass())右值引用函数)。所以我认为这种思维模式是错误的。

那么,思考 xvalue 的“同一性”属性的正确方法是什么?我已经读过,通过身份我可以比较地址,但是如果我可以比较 2 的地址MyClass().member(根据 cppreference 的 xvalue),比方说通过右值引用将它们传递到某个比较函数中,那么我不明白为什么我可以不对 2 MyClass()s(纯右值)做同样的事情吗?

与此相关的另一个来源是此处的答案: 什么是移动语义?

请注意,尽管 std::move(a) 是右值,但其求值不会创建临时对象。这个难题迫使委员会引入第三个价值类别。可以绑定到右值引用的东西,即使它不是传统意义上的右值,也称为xvalue(到期值)。

但这似乎与“可以比较地址”无关,并且a)我不明白这与右值的“传统意义上”有什么不同;b) 我不明白为什么这样的原因需要语言中的新值类别(好吧,这允许为 OO 意义上的对象提供动态类型,但 xvalue 不仅仅指对象)。

c++ xvalue c++14 prvalue value-categories

7
推荐指数
1
解决办法
800
查看次数

MyClass obj = MyClass(); 'MyClass()'是否在这里引用临时对象?

考虑不涉及复制省略的情况(前C++ 17).

从cppreference(再次假设C++ 14):

在以下情况下创建临时对象:

  • 绑定对prvalue的引用
  • 从函数返回一个prvalue
  • 转换,创建一个prvalue
  • lambda表达式
  • 需要转换初始化程序的复制初始化
  • list-initialization,用于构造std :: initializer_list
  • 引用初始化为不同但可转换的类型或位域.

除了第一个案例之外的所有案例似乎都无关紧要,第一个案例似乎意味着C++风格的引用绑定(int &&x = 5;BTW我不明白在这种情况下临时演员在完整表达结束时被销毁的声明......,对象5指的是在语句结尾处似乎没有被销毁).

因此,据我所知,临时对象的概念仅包括那些保证存储的对象(由于可能的省略,在我的情况下不是这种情况).我对么?或者我在这里误解了什么?

BTW有任何区别MyClass(),并4int x = 4;(或2 + 2int x = 2 + 2;)?也许我可能是不正确的,第一个是指临时物体,而另外两个不是......

c++ temporary c++14

7
推荐指数
1
解决办法
302
查看次数

数组new-expression中的Direct-init vs list-init

基本上,为什么这是有效的:

auto p1 = new int[10]{5};

但这不是:

auto p1 = new int[10](5);

更一般地说,new-expression初始化程序的规则是什么?

我找到了以下内容:

- 如果省略new-initializer,则默认初始化对象(8.5).[注意:如果未执行初始化,则对象具有不确定的值. - 结束注释] - 否则,根据8.5的初始化规则解释new-initializer以进行直接初始化.

那么第二种情况是无效的,因为smth就像T((5))是无效的(从表达式直接初始化(5))?或者是什么原因?

编辑:好吧,我对(())事物的建议似乎很愚蠢,因为我认为没有理由为什么只应用于数组new-expression.

c++ initializer language-lawyer c++14 new-expression

7
推荐指数
1
解决办法
213
查看次数

类类型是否会发生左值到右值的转换?

实际上,我在网上看到的每个左值到右值转换的例子都与诸如int等的基本类型有关。

我自己找不到适用于类类型的 l2r 示例;在所有看似适用的例子中,通常有一个函数涉及 lvalue-ref(如 copy-ctor),为此 l2r 似乎被抑制(参见例如这个问题)。

然而,在 l2r 本身的描述中,有一个关于类类型的子句(来自 [conv.lval]):

转换的结果根据以下规则确定:

<...> 如果 T 具有类类型,则转换从泛左值复制初始化 T 类型的临时值,并且转换的结果是临时值的纯右值。

有人可以举一个这个条款的例子吗?我不能。

c++ implicit-conversion lvalue-to-rvalue

7
推荐指数
1
解决办法
114
查看次数

为什么inject-class-name有时不被视为类模板中的模板名称?

资源

在以下情况中,inject-class-name被视为类模板本身的模板名称:

  • 接下来是<
  • 它用作与模板模板参数对应的模板参数
  • 它是友元类模板声明的详细类说明符中的最终标识符.

所以我试图检查所有3个案例(另外在基础模糊的背景下,虽然我认为这不应该在这里).

第一种情况似乎很简单.

问题是 - 为什么没有注释出实例?他们不在GCC和Clang上,所以我不认为这是一个实施问题

template <template <class> class> struct A;

template <class T> struct Base {};

template <class T> struct Derived: Base<int>, Base<char>
{
    // #1
    typename Derived::Base<double> d;

    // #2

    // using a = A<Base>;

    using a = A<Derived::template Base>;

    // #3

    template<class U1>
    friend struct Base;

    // template<class U>
    // friend struct Derived::template Base;
};
Run Code Online (Sandbox Code Playgroud)

以上规则仅适用于模板本身,而不适用于基础吗?如果是这样,基数的规则是什么,特别是对于最后两个案例?

c++ templates c++14 injected-class-name c++17

6
推荐指数
1
解决办法
138
查看次数