使用 decltype 给出警告 Reference to Local Variable
Use of decltype Gives warning Reference to Local Variable
我正在尝试了解 decltype
在 C++ 中的工作原理,因此通过示例。就在我以为我理解它的意思时,我试图创建示例来证实这一点,但我得到了一些我无法理解的东西。示例如下:
#include <iostream>
template<typename T>
auto func2(T a, T b) -> decltype(b < a ? a:b)
{
//return a;//this gives warning of reference to local variable
//return b;//this gives warning of reference to local variable
return (b < a ? a:b);//this does not give warning of reference to local variable
}
int main()
{
std::cout << "Hello World" << std::endl;
int b = func2(4,3);
return 0;
}
如上面的代码所示,当我使用语句 return a;
或 return b;
时,我收到一条警告,指出对局部变量的引用,这是因为我们永远不应该将引用或指向局部变量的指针传递给在他们的范围之外。但我不明白的是 为什么当我使用 return (b < a ? a:b);
.
时我们没有收到相同的警告
我的想法是 decltype(b < a ? a:b)
应该导致 int&
。因此,当我写 return (b < a ? a:b);
时,应该返回对本地 a
或 b
的引用,具体取决于哪个更大,我们应该收到警告。
您不能依赖警告。不写危险代码就得靠自己
从 returns 引用的函数返回 (b < a ? a:b)
是危险的:a
和 b
中的任何一个最终被返回,结果仍然是悬空的参考。在您的情况下,编译器无法捕捉到这一点,因为您返回的表达式太复杂,并且编译器生成警告的任何部分都不够复杂,无法确定此 return
语句将产生一个悬而未决的引用.
唯一万无一失的解决办法就是不要写这样的代码。此外,您需要停止使用“编译器是否发出警告”作为通过实验学习语言规则的方式。太不靠谱了。
But what i don't understand is that why are we not getting the same warning when i use return (b < a ? a:b);
编译器警告的智能程度完全取决于编译器供应商;参见
当您通过编译器警告发现错误时,一般的教训可以说是
Phew, glad my compiler caught that one: I need to understand this construct better
相对于
Why didn't the compiler also catch my other bug?
了解错误出现的构造
I am trying to understand how decltype works in C++ and so going through examples. Just when i thought i understood what it means, i tried to create examples to confirm that and i got something that i cannot understand.
为了完整性,[expr.cond]/5涵盖了三元条件表达式的结果类型,它的最后两个操作数都是相同类型和值类别的左值:
If the second and third operands are glvalues of the same value category and have the same type, the result is of that type and value category and it is a bit-field if the second or the third operand is a bit-field, or if both are bit-fields.
在您的示例中,结果的类型(对于将模板参数推导为 int
的函数参数)是 int
:
void f(int x) {
auto result = false ? x : x;
static_assert(std::is_same_v<decltype(r), int>);
}
[dcl.type.decltype]/1 governs the rules for decltype
, and particularly [dcl.type.decltype]/1.5 适用于此处:
For an expression E, the type denoted by decltype(E) is defined as follows:
- [...]
- /1.5 otherwise, if E is an lvalue, decltype(E) is T&, where T is the type of E;
因此,在您的示例的特定(推导)专业化 func2<int>(...)
中,return 类型被推导为 int&
。
我正在尝试了解 decltype
在 C++ 中的工作原理,因此通过示例。就在我以为我理解它的意思时,我试图创建示例来证实这一点,但我得到了一些我无法理解的东西。示例如下:
#include <iostream>
template<typename T>
auto func2(T a, T b) -> decltype(b < a ? a:b)
{
//return a;//this gives warning of reference to local variable
//return b;//this gives warning of reference to local variable
return (b < a ? a:b);//this does not give warning of reference to local variable
}
int main()
{
std::cout << "Hello World" << std::endl;
int b = func2(4,3);
return 0;
}
如上面的代码所示,当我使用语句 return a;
或 return b;
时,我收到一条警告,指出对局部变量的引用,这是因为我们永远不应该将引用或指向局部变量的指针传递给在他们的范围之外。但我不明白的是 为什么当我使用 return (b < a ? a:b);
.
我的想法是 decltype(b < a ? a:b)
应该导致 int&
。因此,当我写 return (b < a ? a:b);
时,应该返回对本地 a
或 b
的引用,具体取决于哪个更大,我们应该收到警告。
您不能依赖警告。不写危险代码就得靠自己
从 returns 引用的函数返回 (b < a ? a:b)
是危险的:a
和 b
中的任何一个最终被返回,结果仍然是悬空的参考。在您的情况下,编译器无法捕捉到这一点,因为您返回的表达式太复杂,并且编译器生成警告的任何部分都不够复杂,无法确定此 return
语句将产生一个悬而未决的引用.
唯一万无一失的解决办法就是不要写这样的代码。此外,您需要停止使用“编译器是否发出警告”作为通过实验学习语言规则的方式。太不靠谱了。
But what i don't understand is that why are we not getting the same warning when i use return (b < a ? a:b);
编译器警告的智能程度完全取决于编译器供应商;参见
当您通过编译器警告发现错误时,一般的教训可以说是
Phew, glad my compiler caught that one: I need to understand this construct better
相对于
Why didn't the compiler also catch my other bug?
了解错误出现的构造
I am trying to understand how decltype works in C++ and so going through examples. Just when i thought i understood what it means, i tried to create examples to confirm that and i got something that i cannot understand.
为了完整性,[expr.cond]/5涵盖了三元条件表达式的结果类型,它的最后两个操作数都是相同类型和值类别的左值:
If the second and third operands are glvalues of the same value category and have the same type, the result is of that type and value category and it is a bit-field if the second or the third operand is a bit-field, or if both are bit-fields.
在您的示例中,结果的类型(对于将模板参数推导为 int
的函数参数)是 int
:
void f(int x) {
auto result = false ? x : x;
static_assert(std::is_same_v<decltype(r), int>);
}
[dcl.type.decltype]/1 governs the rules for decltype
, and particularly [dcl.type.decltype]/1.5 适用于此处:
For an expression E, the type denoted by decltype(E) is defined as follows:
- [...]
- /1.5 otherwise, if E is an lvalue, decltype(E) is T&, where T is the type of E;
因此,在您的示例的特定(推导)专业化 func2<int>(...)
中,return 类型被推导为 int&
。