我真的不清楚为什么有人会命名一种特定形式的初始化"值初始化".这听起来就像它的给它的值初始化对象......但是这就是初始化不一般,而且名称不告诉你任何关于该珍惜它要使用的初始化.
我尝试了解@bolov对已删除默认构造函数问题的第一个公认答案。仍然可以创建对象...有时 [1]
似乎我在那儿发现了一个错误,因此弄乱了整个解释。
@bolov解释了为什么此代码成功用c ++ 11编译:
方案A
struct foo {
foo() = delete;
};
// All bellow OK (no errors, no warnings)
foo f = foo{};
foo f = {};
foo f{}; // will use only this from now on.
Run Code Online (Sandbox Code Playgroud)
以及为什么此代码无法在c ++ 11中编译:
方案C
struct foo {
foo() = delete;
foo(int) {};
};
foo f{}; // error call to deleted constructor
Run Code Online (Sandbox Code Playgroud)
他说,关键是第一个foo是集合,而第二个foo不是集合。
然后他给出了cppreference的摘录:
T类型的对象的列表初始化的影响是:...
- 如果T是聚合类型,则执行聚合初始化。这照顾了场景ABDE(以及C ++ 14中的F)
否则,将分两个阶段考虑T的构造函数:
所有采用std :: initializer_list的构造方法...
否则,T的所有构造函数都将参与重载解析[...],这将照顾到C(和C ++ 11中的F)...
根据摘录,当你写foo …
简而言之,为什么下面的代码表现得像评论中描述的那样?
struct A
{
A() = delete;
//A(const A&) {} // uncommenting this...
};
int main()
{
A a{}; // ... breaks this
//A(); // this fails in either case because of `A() = delete;` only
}
Run Code Online (Sandbox Code Playgroud)
我应该查看标准的哪一部分(或至少是 cppreference 上的一页)来理解这一点?
但是,写入A(const A&) = default;而不是//A(const A&) {} 不会中断A a{};。那这个呢?我认为根本原因是相同的,但是真正了解 C++ 的人的一句话比我认为的要好。
c++ default-constructor language-lawyer value-initialization c++11
我看到g ++和msvc在初始化不可复制对象的值之间有一些不同的行为.考虑一个不可复制的类:
class noncopyable_base
{
public:
noncopyable_base() {}
private:
noncopyable_base(const noncopyable_base &);
noncopyable_base &operator=(const noncopyable_base &);
};
class noncopyable : private noncopyable_base
{
public:
noncopyable() : x_(0) {}
noncopyable(int x) : x_(x) {}
private:
int x_;
};
Run Code Online (Sandbox Code Playgroud)
和一个使用值初始化的模板,以便即使类型为POD,该值也将获得已知值:
template <class T>
void doit()
{
T t = T();
...
}
Run Code Online (Sandbox Code Playgroud)
并尝试将它们一起使用:
doit<noncopyable>();
Run Code Online (Sandbox Code Playgroud)
从VC++ 9.0开始,这在msvc上运行正常,但在每个版本的g ++上都失败了我用它(包括版本4.5.0)进行了测试,因为复制构造函数是私有的.
两个问题:
T t;为不可接受的解决方案,因为这会打破POD类型).PS我看到与boost :: noncopyable相同的问题.
考虑
#include <vector>
int main()
{
std::vector<int> foo;
foo.resize(10);
// are the elements of foo zero?
}
Run Code Online (Sandbox Code Playgroud)
元素foo全为零吗?我认为它们是从 C++11 开始的。但想确切地知道。
今天我开始了解C++中有3种类型的初始化:
我搜索了它,但我没有找到满意的结果.我得到的只是一些标准.到目前为止我所理解的是:在值初始化的情况下,数据成员在某些情况下可以获得等于零的值.
请用示例详细说明它们(标准).另外,请不要只提供标准中的文字.
谢谢
在这段代码中:
signed char v = -64;
int n = 4;
int x = v - '0' * (signed char)n;
std::cout << x << std::endl;
Run Code Online (Sandbox Code Playgroud)
应该x是-5还是-261?以我的理解,初始化器表达式具有signed char类型,一旦计算了初始化器,类型转换应在以后进行。
所以,v - '0' * (signed char)n应该等于-5因为这相当于价值-261的signed char估值。
但是,那段代码打印出来了-261。
考虑以下程序(请参阅此处的实时演示)
import std.stdio;
void main()
{
int i=int();
writefln("i is %d",i);
}
Run Code Online (Sandbox Code Playgroud)
在像C++这样的语言中,该语句int i=int();称为值初始化.对于类型int,值初始化基本上最终为零初始化.如果我没有错,C++标准保证它总是给我零.但D语言是否包含像C++一样的值初始化功能?是否必须在所有D编译器和我在D程序上编译和运行的每个环境中给出零值?
这个问题仅涉及预C++ 11.考虑以下看似破碎的代码:
struct X
{
X(){} // default user-provided constructor
private:
X(const X&){}
};
int main()
{
X x = X();
}
Run Code Online (Sandbox Code Playgroud)
根据cppreference.com在预C++ 11中的默认ctor将被调用:
值初始化的效果是:
1)如果T是具有至少一个用户提供的任何类型构造函数的类类型,则调用默认构造函数;
...
这似乎意味着复制文件不一定需要访问.这是否正确?上面的代码不能编译,因此似乎必须可以访问复制ctor .
给定两个具有不同构造函数的类:
#include <iostream>
struct A {
int x;
A() {};
};
struct B {
int x;
B() = default;
};
int main() {
int x = 5;
x = 7;
printf("before: %d\n", x);
new(&x) A();
printf("%d\n", x);
new(&x) B();
printf("%d\n", x);
}
Run Code Online (Sandbox Code Playgroud)
输出是:
before: 7
7
0
Run Code Online (Sandbox Code Playgroud)
为什么defaultctor 会进行零初始化int x?
struct MyType {
const char *pointer{""};
};
struct MyTypeHolder {
MyType my_type;
MyType &GetMyType() { return my_type; }
};
int main () {
MyTypeHolder my_type_holder;
auto &my_type = my_type_holder.GetMyType();
my_type = MyType{};
// May one assert that my_type.pointer points to the empty string?
}
Run Code Online (Sandbox Code Playgroud)
在上面的示例中,my_type = MyType{}类型的临时对象MyType被值初始化。因为MyType非静态成员有一个默认的成员初始值设定项,pointer所以一旦对象被值初始化,就可以断言 指向空字符串吗?