对成员对象内联使用非默认显式构造函数
Inline use of non-default explicit constructor for a member object
在C++11(或未来)中,是否存在以下合法的简单变体?
class A
{
public:
std::vector<char> b(123); // declare a vector with 123 elements
};
我能找到的最接近的是有点笨重,而且可能效率低下。。。
class A
{
public:
std::vector<char> b = std::vector<char>(123);
};
我尽量避免使用初始值设定项列表。我更喜欢将b
的声明和初始化合并为一行代码。矢量的大小始终相同。
我在这个例子中使用的是std::vector
,但可能答案更普遍适用。
为了更好地衡量,以下是来自gcc
版本4.8的错误消息:
错误:数字常量之前应为标识符std::矢量b(123);
这是clang
3.7版的消息:
错误:需要参数声明符std::矢量b(123);
极不可能。最初允许NSDMI的提案首先解决了这个问题:
N2756
科纳提出的关于标识符范围的问题:
在2007年9月的核心工作组讨论中在科纳举行的会议上,出现了一个关于初始化器。我们想允许类范围有可能正向查找;还是要求初始化程序在解析时定义明确?
所需内容:
类范围查找的动机是我们希望能够在非静态数据成员的初始值设定项中放入我们可以在不显著更改语义的情况下放入mem初始值设定项(模直接初始化与复制初始化):
int x(); struct S { int i; S() : i(x()) {} // currently well-formed, uses S::x() // ... static int x(); }; struct T { int i = x(); // should use T::x(), ::x() would be a surprise // ... static int x(); };
问题1:
不幸的是,这使得"(表达式列表)"的初始值设定项在解析声明时形式不明确:
提案:
CWG在科纳进行了6比3的民意调查,支持阶级范围查找;这就是本文提出的,使用非静态的初始化器限制为"=初始值设定项子句"answers"{初始值设定项列表}"形式。我们相信:
问题1:由于我们没有提出(),因此不会出现此问题符号=和{}初始值设定项符号不受此影响问题
除非你的编译器不采用复制省略(所有主要的编译器都采用了),否则这种笨拙的初始化方式并没有什么效率低下的地方。问题是C++的语言设计者已经把自己逼到了一个角落。因为初始值设定项列表构造函数是贪婪的,所以大括号初始化将使用给定的元素构造一个向量,而使用括号的旧语法则调用显式构造函数来设置大小。
但你不能在NSDMI中使用那个构造函数。除非你用等号。
如果出于某种原因让你感到困扰,有一些笨拙的解决方法:
std::vector<char> c = decltype(c)(123);
// ...
using VChar = std::vector<char>;
VChar v = VChar(123);
或者意识到新功能并不排除现有功能:
std::vector<char> c;
A() : c(123)
{
}
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 初始化具有非默认构造函数的std::数组项的更好方法
- 具有默认模板类型的默认构造函数的类型推导
- 如何使用非默认构造函数实例化模板化类
- 有没有一种代码密度较低的方法来使用非默认构造函数初始化数组?
- 声明没有默认构造函数的字段
- 没有默认构造函数作为模板参数的自定义比较器
- C++17 没有默认构造函数的地图放置(私有默认构造函数)
- 使用移动调用对等构造函数unique_ptr默认构造函数
- C++复制构造函数和默认构造函数
- 将向量从 N1 缩小到 N2 项,而不触发默认构造函数并仅使用 move 语义
- 为什么即使我调用参数化构造函数也会调用默认构造函数?
- 具有非默认构造函数的单例类
- 在 C++ 中声明 const 对象需要用户定义的默认构造函数.如果我有一个可变成员变量,为什么不呢?
- 如何处理没有默认构造函数但在另一个构造函数中构造的对象?
- 在C++中使用默认构造函数初始化对象的不同方法
- 在没有默认构造函数的情况下创建的派生对象
- 强制使用默认构造函数对成员进行未初始化的声明
- 使用默认构造函数初始化对象的不同方法
- 创建类类型的动态分配数组,其中类不得具有默认构造函数