![](/img/trans.png)
[英]perf record with --call-stack fp fails to unwind main function
[英]How does the following code work to uniquely instantiate a template function everytime for a unique call-stack?
我遇到了以下来自Unreal Engine源代码的代码
namespace UE4Asserts_Private
{
// This is used by ensure to generate a bool per instance
// by passing a lambda which will uniquely instantiate the template.
template <typename Type>
bool TrueOnFirstCallOnly(const Type&)
{
static bool bValue = true;
bool Result = bValue;
bValue = false;
return Result;
}
FORCEINLINE bool OptionallyDebugBreakAndPromptForRemoteReturningFalse(bool bBreak, bool bIsEnsure = false)
{
if (bBreak)
{
FPlatformMisc::DebugBreakAndPromptForRemoteReturningFalse(bIsEnsure);
}
return false;
}
}
#define ensure( InExpression ) (LIKELY(!!(InExpression)) || FDebug::OptionallyLogFormattedEnsureMessageReturningFalse(UE4Asserts_Private::TrueOnFirstCallOnly([]{}), #InExpression, __FILE__, __LINE__, TEXT("") ) || UE4Asserts_Private::OptionallyDebugBreakAndPromptForRemoteReturningFalse(UE4Asserts_Private::TrueOnFirstCallOnly([]{}), true))
现在,每当我们使用ensure(SomeExpression)
该UE4Asserts_Private::TrueFirstCallOnly
参数FDebug::OptionallyLogFormattedEnsureMessageReturningFalse
计算结果为真实的,只有在第一次被调用特定的调用堆栈(我每次调用堆栈想,作为TrueOnFirstCallOnly
计算结果为假的下一次调用来自同一调用堆栈的确保,但从不同的调用堆栈触发确保但不是很确定),我不明白这是如何工作的。
正如他们在评论中所述,以某种方式将 lambda []{}
传递给模板函数会唯一地实例化它。 它是如何工作的? 什么是作为模板传递的 lambda 真正独特的,它是调用堆栈还是其他什么?
如果表达式为真,则LIKELY(!!(InExpression))
可以被认为评估为真
这就是如何实现这样的true_on_first_call
:
include <iostream>
template <typename T> struct true_on_first_call {
static bool first;
bool operator()() {
if (first) {
first = false;
return true;
}
return false;
}
};
template <typename T> bool true_on_first_call<T>::first = true;
template <typename T>
bool get_true_on_first_call(const T &){ return true_on_first_call<T>()(); }
void foo() {
std::cout << get_true_on_first_call([]{}) << "\n"; // instantiation for []{}
}
void bar() {
std::cout << get_true_on_first_call([]{}) << "\n"; // instantiation for []{}
} // note: its a different type
// than the []{} above!
// but the same on
// repeated calls to foo
int main() {
std::cout << "first \n";
foo();
bar();
std::cout << "second \n";
foo();
bar();
}
诀窍是每个 labmda 表达式都有一个唯一的类型,因此它会导致true_on_first_call
的不同实例化。 即使 lambdas 表达式相同( []{}
与[]{}
),它们的类型也不同。 另一方面,相同的 lambda 表达式(即第一次调用foo
表达式和第二次调用foo
表达式)是相同的类型。 通过这种方式,您每次编写get_true_on_first_call([]{})
时都可以获得唯一的实例化。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.