我尝试了以下方法
auto ns=ms.capture[0].init,nl=ms.capture[0].len;
因为我懒得查找init
和len
字段的类型。编译器当然不喜欢它。
我的理解是:
ttt xx,yy;
相当于
ttt xx;ttt yy;
那么同样应该适用于auto
吗?也就是说,不应该
auto xx, yy;
成为:
auto xx, auto yy;
还是有什么我不明白的细节?还是我的编译器有问题?
auto
是类型扣除的占位符。在您这里的情况下,它是从初始值设定项推断出来的。
正如你所说:
T1 a, b;
相当于:
T1 a; T1 b; // (A)
但不等同于:
T1 a; T2 b; // (B)
因此,当您编写:
auto ns=ms.capture[0].init,nl=ms.capture[0].len;
编译器很难确定基础类型,因为init
成员是const char *
,而len
成员是int
(根据您的错误消息)。您提供了两个不同类型的初始值设定项。我们处于上述示例的(B)中。
因此,类型推断失败。
为简单起见,如果可以将auto
说明符替换为实际类型(此处不是这种情况),则代码将有效。
正如你所说,(法雷诺说)
ttt xx,yy;
相当于
ttt xx;ttt yy;
所以这是不可能的
auto xx,yy = ...;
推论
char* xx, int yy = ...;
auto
以你编写的方式,它只能推断出一种类型。您正在寻找的是"元组初始化"。我在引号中这样说,因为它不是真实的东西,但是C++和其他语言中有一个共同的模式,看起来像你正在做的事情。
例如,在Python中:
xx, yy = "foo", 42
确实会像您期望的那样初始化xx
和yy
。
在 C++17 之前的C++中,您可以通过元组分配来实现这一点:
char* xx;
int yy;
std::bind(xx, yy) = std::make_tuple("foo", 42);
(C# 的工作方式几乎相同)。这不是很好;你被迫声明你的类型,然后通过bind
将对这些类型的引用包装在一个元组中,最后执行赋值。这意味着你无法利用copy elision,你的类型要么需要默认可构造,要么使用无意义的参数调用构造函数。
但是,在 C++17 之后,我们可以使用结构化绑定,我们可以在其中获得类型推断、复制省略和所有好东西。
现在我们可以说:
auto [xx, yy] = // array/tuple-like/POD-type
我们将获得适合xx
和yy
的类型.下面是一个近似于您发布的代码的示例:
struct Member{
const char* init = "foo";
int len = 42;
};
struct Test{
std::vector<Member> capture{Member{}};
};
int main()
{
Test ms;
auto [ns, nl] = ms.capture[0];
}