提问人:Tony J 提问时间:10/20/2023 更新时间:10/20/2023 访问量:114
为什么使用条件运算符?:导致返回本地临时对象?
Why does using conditional operator ? : causes returning local temporary object?
问:
我遇到了一个问题,即使用条件运算符在 MSVC 中返回垃圾string_view,因为string_view是由临时对象支持的?。
#include <string>
#include <iostream>
std::string hello("Hello");
char world[6] = { "World" };
std::string_view ChooseString( bool first )
{
// warning: returning address of local temporary object
return first ? hello : world; // returned string_view is garbage
// all other ways of returning string_view works fine
/*if ( first )
return hello;
else
return world;*/
//return first ? std::string_view( hello ) : std::string_view( world );
//return hello;
//return world;
}
int main()
{
std::cout << ChooseString(true) << std::endl;
std::cout << ChooseString(false) << std::endl;
}
然后我在 goldbot 上尝试了 clang 和 gcc,它们有相同的行为,其中 clang 发出警告:返回本地临时对象的地址。另外,只是返回你好或世界也很好。有人可以解释为什么第一种方式返回临时对象吗?
是因为在计算条件运算符后构造了字符串对象吗?
答:
7赞
songyuanyao
10/20/2023
#1
是的,条件运算符的返回类型是操作数的常见类型。给定 ,即操作数的类型是 和 ,公共类型将是 。需要构造一个临时,然后使用临时来构造稍后返回的。first ? hello : world;
std::string
const char[]
std::string
std::string
world
std::string_view
另一方面,对于返回类型是 ,并且所有 s 都是由 和 直接构造的,那么没有如上所述的问题。first ? std::string_view( hello ) : std::string_view( world )
std::string_view
std::string_view
hello
world
评论
0赞
Tony J
10/20/2023
我也会从真中得到垃圾,这是否意味着也创建了临时副本?为什么编译器不推断为通用类型?hello
first
hello
string_view
0赞
songyuanyao
10/20/2023
@TonyJ,我想作为实现,总会返回一个,要么从 或 .std::string
hello
world
2赞
user229044
10/20/2023
@TonyJ 编译器不会这样做,因为这不是C++。表达式的使用方式永远不会决定表达式的类型。结果就是结果,在生成后会转换为其他类型,但结果的使用方式不会影响表达式的计算方式。如果可行,您可以仅根据函数的返回类型重载函数;你不能,因为这不是 C++ 的工作方式。
1赞
songyuanyao
10/20/2023
@TonyJ关于返回类型,编译器找到的可以转换为然后被推导为通用类型。它不会进一步检查。有关详细信息,请参阅此处。const char[]
std::string
std::string
1赞
Pete Becker
10/20/2023
@user229044——永远不要说永远。当您获取重载函数的地址时,它会因使用方式而消除歧义。之后,例如,选择第一个,然后选择第二个。也就是说,表达式的类型由强制转换决定。叹息。是的,这会分散注意力。void f(); void f(int)
(void(*)())f
(void(*)(int))f
f
评论
?
std::string
world
string_view
first ? hello : world
hello
world
hello
std::string
world
char
first ? hello : world
world
std::string
std::string
std::string_view
if
else
std::string_view