相关疑难解决方法(0)

为什么标准区分直接列表初始化和复制列表初始化?

我们知道这T v(x);被称为直接初始化,而T v = x;被称为复制初始化,这意味着它将构造一个临时Tx,将被复制/移入v(很可能被省略).

对于列表初始化,标准根据上下文区分两种形式.T v{x};称为直接列表初始化,T v = {x};称为复制列表初始化:

§8.5.4 [dcl.init.list] p1

[...]列表初始化可以在直接初始化或复制初始化上下文中进行; 直接初始化上下文中的列表初始化称为直接列表初始化,复制初始化上下文中的列表初始化称为复制列表初始化.[...]

但是,整个标准中只有两个引用.对于直接列表初始化,在创建像T{x}(§5.2.3/3)这样的临时表时会提到它.对于copy-list-initialization,它用于返回语句中的表达式,如return {x};(§6.6.3/2).

现在,下面的片段怎么样?

#include <initializer_list>

struct X{
  X(X const&) = delete; // no copy
  X(X&&) = delete; // no move
  X(std::initializer_list<int>){} // only list-init from 'int's
}; …
Run Code Online (Sandbox Code Playgroud)

c++ language-lawyer c++11 list-initialization

37
推荐指数
1
解决办法
2782
查看次数

我们可以通过函数的值返回具有已删除/私有复制/移动构造函数的对象吗?

在C++ 03中,不可能通过值返回具有私有非定义复制构造函数的类的对象:

struct A { A(int x) { ... } private: A(A const&); };

A f() {
  return A(10); // error!
  return 10;    // error too!
}
Run Code Online (Sandbox Code Playgroud)

我想知道,这个限制是否在C++ 11中解除了,是否可以编写具有类类型返回类型的函数,而没有用于复制或移动的构造函数?我记得允许函数的调用者使用新返回的对象可能很有用,但是他们无法复制值并将其存储在某处.

c++ copy-constructor c++11

16
推荐指数
3
解决办法
2787
查看次数

数组成员初始化用户定义的类型

g ++ 4.7支持数组成员初始化,我开始玩它.

下面的代码无法编译.

struct A
{
   A(int){};
   A(const A&) = delete;
   A& operator=(const A&) = delete;
   ~A(){};
};

struct B
{
   B():
      a{{0},{1}}
   {};
   A a[2];
};

B b;
Run Code Online (Sandbox Code Playgroud)

gcc 4.8(预发布)的错误消息是:

n.cc: In constructor ‘B::B()’:
n.cc:12:20: error: use of deleted function ‘A::A(const A&)’
           a{{0},{1}}
             ^
n.cc:4:8: error: declared here
        A(const A&) = delete;
        ^
Run Code Online (Sandbox Code Playgroud)

有没有办法让这段代码有效?我不能轻易地改变A的构造函数,析构函数.我似乎需要一个move-constructor或copy-constructor来初始化数组,但这似乎是违反直觉的,因为我真正想要的就是就地构造.

如果我在2个成员a0和a1中分割[2]并分别构造它们,它就可以工作.然而,这看起来很可疑.

c++ constructor c++11

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