正在使用“var{args}”进行初始化C++0x 的新功能,还是仅仅是语法糖?

发布于 2024-11-29 20:50:10 字数 396 浏览 2 评论 0原文

我正在阅读 C++0x 常见问题 并遇到了详细说明初始值设定项列表的部分。这些例子大多是以下形式的变体:

vector<int> vi = { 1, 2, 3 };
vector<int> vj({1, 2, 3});
// etc.

然而,还列出了以下形式:

vector<int> vk{2};

这种形式出现在常见问题解答中的其他地方,我很好奇它在语义上是否与最初的两种形式不同,或者只是 vk( 的语法糖{x,y,z})

I was reading the C++0x faq and came across the section detailing initializer lists. The examples were mostly variations of:

vector<int> vi = { 1, 2, 3 };
vector<int> vj({1, 2, 3});
// etc.

However, also listed was the form:

vector<int> vk{2};

This form appears elsewhere in the faq, and I am curious as to whether it is semantically different from the initial two forms, or just syntactic sugar for vk({x, y, z}).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

べ映画 2024-12-06 20:50:10

({1, 2, 3}) 形式直接调用 vector 的构造函数,并传递 {1, 2, 3 作为第一个参数}。 您可以传递更多参数

vector<int> vk({1, 2, 3}, myAllocator);

如果 vector 没有第一个参数是 initializer_list 或可由 {1 初始化的其他类型的构造函数, , 2, 3} (就像另一个容器类),它不起作用。在您的情况下,它可以工作,因为 vector 实际上有一个构造函数,其第一个参数是 initializer_list。这就像在普通函数调用中一样

void f(vector<int> const& vk);
int main() { f({1, 2, 3}); }

如果省略括号,如 vector; vk{1, 2, 3},具体含义取决于类。 vector 有一个初始化列表构造函数,它是一个第一个参数为 initializer_list 类型的构造函数(可以选择对其的引用),以及所有其他具有默认参数的 params。如果该类具有这样的构造函数,则初始值设定项列表将传递给该构造函数。或者,该类可以只是一个聚合(例如 struct A { int a; int b; int c; };,初始化器列表将初始化成员)或具有接受 的构造函数3 单独的 int 参数。

最后, = { 1, 2, 3 } 形式与省略括号的版本几乎相同(即仅删除 =),除了它禁止使用显式构造函数(即他们将其声明为显式向量(initializer_list);或者他们将其声明为显式向量(int, int, int);,如果您使用 = { 1, 2, 3 }),则会导致错误。

The ({1, 2, 3}) form calls the constructors of vector<int> directly, and passes as first argument a {1, 2, 3}. You could have passed more arguments

vector<int> vk({1, 2, 3}, myAllocator);

If vector<int> would not have a constructor whose first parameter is an initializer_list or of another type that could be initialized by {1, 2, 3} (like, another container class), it would not work. In your case it works because vector<int> in fact has a constructor whose first parameter is a initializer_list<int>. This is just like in normal function calls

void f(vector<int> const& vk);
int main() { f({1, 2, 3}); }

If you omit the parentheses, as in vector<int> vk{1, 2, 3}, the exact meaning depends on the class. A vector<int> has an initializer list constructor, which is a constructor with a first parameter of type initializer_list<int> (optionally a reference to it), and all other params with default arguments. If the class has such a constructor, then the initializer list is passed to that constructor. Alternatively the class could simply be an aggregate (like struct A { int a; int b; int c; };, the initializer list would then init the members) or have a constructor that accepts 3 separate int arguments.

Finally the = { 1, 2, 3 } form is almost identical to the version omitting the parentheses (i.e just removing =), except that it forbids to use explicit constructors (i.e had they declared it as explicit vector(initializer_list<int>); or had they declared a explicit vector(int, int, int); instead, it would result in an error if you use = { 1, 2, 3 }).

荒人说梦 2024-12-06 20:50:10

一种是统一初始化,另一种是初始化器列表。它们是两个不同的东西,尽管如您所见,它们可以产生相似的语法。

vector<int> vk{2};

是统一初始化 - 其他两个是初始化列表。

One is uniform initialization, and the other is initializer lists. They are two different things, although as you can see, they can produce similar syntax.

vector<int> vk{2};

is a uniform initialization- the other two are initializer lists.

雾里花 2024-12-06 20:50:10

统一初始化可防止缩小转换范围,即会导致数据丢失的转换:

#include <vector>

std::vector<float> v{1.0F, 2.0F, 3.0F}; // OK: 

std::vector<float> w{1.0, 2.0, 3.0}; // OK: doubles could be put into floats without loss.

std::vector<int> j{1.1, 2.2, 3.3}; // error: narrowing

std::vector<int> k{1L, 2L, 3L}; // OK: the long numbers can be represented as int without loss.

std::vector<int> l{0xfacebeefL, 0xdeadbabeL, 0xfadecabeL}; // error: narrowing.

The uniform initialization prevents narrowing conversions i.e. conversions that would cause loss of data:

#include <vector>

std::vector<float> v{1.0F, 2.0F, 3.0F}; // OK: 

std::vector<float> w{1.0, 2.0, 3.0}; // OK: doubles could be put into floats without loss.

std::vector<int> j{1.1, 2.2, 3.3}; // error: narrowing

std::vector<int> k{1L, 2L, 3L}; // OK: the long numbers can be represented as int without loss.

std::vector<int> l{0xfacebeefL, 0xdeadbabeL, 0xfadecabeL}; // error: narrowing.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文