gpt4 book ai didi

c++ - 为什么通过地址传递大括号初始化的临时变量需要显式转换为 MSVS 中的相同类型

转载 作者:太空狗 更新时间:2023-10-29 19:38:32 25 4
gpt4 key购买 nike

在处理 Windows API 时,我试图通过替换两行代码来使我的代码不那么臃肿

TEMP t{0,1,2}; // let's say it's struct TEMP {int a; int b; int c}
SomeVeryVerboseFunctionName(&t);

单行

SomeVeryVerboseFunctionName(&TEMP{0,1,2});

但偶然发现错误:

expression must be an lvalue or function designator.

经过多次尝试,我终于想出了可以编译的代码(MSVS 2013u4):

SomeVeryVerboseFunctionName(&(TEMP) TEMP{0,1,2});//explicit cast to the same type!

为了更好地理解为什么需要转换,我设置了一个简单的测试项目:

#include <stdio.h>

struct A
{
int a;
int b;
A(int _a, int _b) : a(_a), b(_b) {};
};

struct B
{
int a;
int b;
};

template <typename T> void fn(T* in)
{
printf("a = %i, b = %i\n", in->a, in->b);
}

int main()
{
fn(&A{ 1, 2 }); //OK, no extra magick
/* fn(&B {3, 4}); //error: expression must be an lvalue or function designator */
fn(&(B)B{ 3, 4 }); //OK with explicit cast to B (but why?)
}

并且发现如果一些结构 T 有一个显式构造函数(就像上面代码中的 A 有),那么就可以获取类型为 T 的大括号初始化的临时地址并将其传递给一个接受指针 T* 的函数,但如果它没有指针(如 B ),则会出现上述错误,并且只能通过显式转换为类型 T 来克服。

所以问题是:为什么 B 需要这种奇怪的转换而 A 不需要?

更新

现在很明显,将右值视为左值是 MSVS 中的一个扩展/功能/错误,有没有人愿意假装它实际上是一个功能(自 2010 年以来足以让 MS 维护它)并详细说明为什么 AB 需要通过不同的方式传递才能满足编译器?肯定和A的构造函数有关,而B没有构造函数……

最佳答案

你所做的实际上在 C++ 中是非法的。

Clang 3.5 提示:

23 : error: taking the address of a temporary object of type 'A' [-Waddress-of-temporary]
fn(&A {1, 2}); //OK, no extra magick
^~~~~~~~~

25 : error: taking the address of a temporary object of type 'B' [-Waddress-of-temporary]
fn(&(B) B {3, 4}); //OK with explicit cast to B (but why?)
^~~~~~~~~~~~~

All operands of & must be lvalues ,不是临时的。 MSVC 接受这些构造的事实是一个错误。根据link上面的 Shafik 指出,MSVC 似乎错误地为这些创建了左值。

关于c++ - 为什么通过地址传递大括号初始化的临时变量需要显式转换为 MSVS 中的相同类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31296834/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com