Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/139.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 初始化表达式的每种方法的优缺点是什么?_C++_C++11_C++14 - Fatal编程技术网

C++ 初始化表达式的每种方法的优缺点是什么?

C++ 初始化表达式的每种方法的优缺点是什么?,c++,c++11,c++14,C++,C++11,C++14,这本书的灵感来自安德烈·亚历山德雷斯库(Andrei Alexandrescu)的作品 使用以下方法初始化表达式的利弊是什么?什么时候我应该选择一个而不是另一个 auto v = expr; T v = expr; auto v(expr); T v(expr); auto v { expr }; T v {expr}; auto v=expr;tV=expr很好,但是在自动版本中,可能很难理解expr的类型 例如,在auto x=snafuscate()中,x的类型是什么 在存在歧义的情况

这本书的灵感来自安德烈·亚历山德雷斯库(Andrei Alexandrescu)的作品

使用以下方法初始化表达式的利弊是什么?什么时候我应该选择一个而不是另一个

auto v = expr;
T v = expr;
auto v(expr);
T v(expr);
auto v { expr }; 
T v {expr};

auto v=expr;tV=expr
很好,但是在自动版本中,可能很难理解
expr
的类型

例如,在
auto x=snafuscate()中,x的类型是什么

在存在歧义的情况下,最好将右侧的类型显式声明为:
autox=Gadget{snafuscate()}

autov(expr)
tv(expr)
是个坏主意,因为有效的
expr
也可以理解为函数指针

此代码不编译:

int main()
{
    int x(int());
    return x + 3;
}

prog.cpp:4:11: error: invalid conversion from ‘int (*)(int (*)())’ to ‘int’ [-fpermissive]
return x + 3;
         ^

autov{expr}几乎总是错误的,因为v的类型变成了初始值设定项列表而不是T


有关自动的最佳实践,请参见:

除了含义不同的情况(例如,
vectorv(12)
不会给您一个值为12的向量),编译器应该为上述所有内容提供相同的内容,并且实际上只是个人偏好决定了哪个“更好”


auto
在类型难以键入且类型从上下文中清除时非常有用。但
autox=12很难区分它是有符号的还是无符号的,例如[我不知道规则,可能是有符号的]

我认为,不必使用自动作为

auto x = 12332; // or
auto z = 0xffff; //
因为

auto x = 12332; // type is  'int'
auto x2 = 0xffff // type is 'int'
auto y = 0xffffffff; // 8 fs,  type is unsigned int
auto z = 0xfffffffff;// 9 fs,  type is long long
auto t = 0xffffffffffffffff; // 16 fs, type is unsigned long long.
但是,你可以使用

auto size = array.size();

这是一个相当困难的问题

有两个不同的问题

第一个是是否使用类型推断,即使用
auto
说明符或显式指定类型。一般来说,我认为最好显式指定类型以帮助提高可读性,除非类型很长且很麻烦(例如迭代器):

或者,如果初始值设定项中的类型很明显:

auto pfoo = new Foo(x,y,z);
或者如果你不关心可读性

第二个问题是使用什么类型的初始化。有直接初始化、复制初始化和列表初始化,而初始化的行为在很大程度上取决于目标的类型。在C++标准的第8.5节中描述了它们之间的差异。此外,除了简单的声明之外,初始化在更多的地方出现。初始化发生在参数传递、返回值、子表达式、语句条件、数组边界和许多其他地方。这确实是一件你需要了解细节的事情,一些简短的总结并不能减少它

auto v = expr;
auto v(expr);
当您在代码中不知道
expr
的类型并希望保持通用性时,或者在代码中完全清楚
expr
的类型(定义就在上面一行,等等),这样
auto
就不会增加混淆

初始化的形式,不管是否是parens,都是不相关的(只与语言律师相关,因为存在细微的差异)。使用你觉得更舒服的东西


如果您的代码中不清楚什么是
expr
(定义相距太远等),或者您不知道
expr
的类型,但希望
v
属于
t
类型。如果要继续使用“expr”所具有的“值类型”(即
expr
是字符串,而
T
是字符串类型),请使用第一种形式。如果您建立了一种全新的值(即
小部件
,并且
expr
是小部件的颜色),请使用第二种形式


在当前的C++中(不在未来几年内)不要使用它。它将声明

v
std::initializer\u列表
。如果您需要,请直接使用该类型并将其写出。这太微妙了(有人建议beyond-C++14来改变这一事实,所以希望您可以用C++17或类似的语言编写)


如果您想保护自己不受转换范围的限制(即从
1000
意外地转换为
char
),或者如果您想初始化具有初始值设定项列表构造函数的类,或者如果您有一个要初始化的成员的聚合,请使用此表单。或者,如果您处理的是初始值设定项列表构造函数、聚合或简单非类类型,则可以使用以下命令

T v = { expr };
我不会用它来调用任意构造函数。我会使用下面的表格

T v(expr);

然而,也有人更喜欢使用大括号形式。我想确定我的代码在做什么,因此当我想调用构造函数,而不想随机执行聚合或列表初始化构造函数调用时,我会使用括号而不是大括号。

只要它更容易阅读。例如,
auto p=std::make_shared(1,2,3)。任何时候,描述性函数都会返回一些明显的难以键入的内容—迭代器、引用包装器、弱指针锁等。所有这些都取决于
T
expr
。例如,如果<代码> t>代码>是代码> int <代码>,我将不使用<代码> Auto < /Cord>。@ KrErkSB,但是一些C++ Grurs认为上面最丑陋的语法之一更为可取,具体地说是代码> AutoV{ExpR};代码>我想知道why@pyCthon:品味问题?问题当然是
tx(U())
是一个函数声明,因此
tx{expr}
是更安全的建议。同上,不需要隐式复制构造函数。我仍然认为它比“通常”的语法更难看。
autov{expr}
几乎总是错误的;它提供了一个
std::initializer\u列表
而不是
T
auto x=12
带符号整数
自动x=12u
无符号整数
@xlc:和
自动y=123456789876
<代码>自动z=0x1234auto v { expr };
T v {expr};
T v = { expr };
T v(expr);