内联使用成员对象的非默认显式构造函数

nob*_*bar 2 c++ c++11 c++17

在C++ 11(或未来)中,是否有以下简单的变体是合法的?

class A
   {
public:
   std::vector<char> b(123); // declare a vector with 123 elements
   };
Run Code Online (Sandbox Code Playgroud)

我能找到的最近的有点笨重,也许效率低下......

class A
   {
public:
   std::vector<char> b = std::vector<char>(123);
   };
Run Code Online (Sandbox Code Playgroud)

我试图避免使用初始化列表.我更喜欢将声明和初始化b合并为一行代码.矢量将始终具有相同的大小.

std::vector在这个例子中使用,但可能答案更普遍适用.


为了更好地衡量,这是gcc版本4.8 的错误消息:

错误:数字常量std :: vector b之前的预期标识符(123);

这是clang3.7版本的消息:

错误:期望参数声明符std :: vector b(123);

use*_*536 6

不大可能.最初允许NSDMI的提议解决了这个问题:

N2756

Kona在标识符范围方面提出的问题:

在2007年9月Kona会议的核心工作组讨论期间,出现了关于初始化程序中标识符范围的问题.我们是否希望允许类范围具有正向查找的可能性; 或者我们是否要求在解析它们时明确定义初始化器?

你想要什么:

类范围查找的动机是我们希望能够将任何内容放入非静态数据成员的初始化程序中,我们可以将其放入mem-initializer而不会显着改变语义(模数直接初始化与复制初始化) :

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();
};
Run Code Online (Sandbox Code Playgroud)

问题1:

不幸的是,这使得" ( 表达式列表 ) "的初始化器在解析声明时形式不明确:

...

提案:

CWG在Kona进行了6比3的民意调查,支持分类范围查询; 这就是本文提出的内容,非静态数据成员的初始化程序仅限于" = initializer-clause "和" { initializer-list } "形式.我们相信:

问题1:由于我们不提出() 表示法,因此不会出现此问题.该={}初始化符号不存在这个问题.

除非您的编译器不使用复制省略(并且所有主要的复制省略),否则关于笨重的初始化方式没有任何低效率.问题是C++的语言设计者已经将自己置于一个角落.因为初始化列表构造函数是贪心的,所以大括号初始化将使用给定元素构造向量,而使用括号的较旧语法调用显式构造函数来设置大小.

除非你不能在NSDMI中使用该构造函数.除非你使用等号.

如果由于某种原因困扰你,有一些笨重的解决方法:

std::vector<char> c = decltype(c)(123);
// ...
using VChar = std::vector<char>;
VChar v = VChar(123);
Run Code Online (Sandbox Code Playgroud)

或者意识到新功能并不排除现有功能:

std::vector<char> c;

A() : c(123)
{
}
Run Code Online (Sandbox Code Playgroud)