gpt4 book ai didi

c++ - 以下代码如何工作以每次为唯一的调用堆栈唯一地实例化模板函数?

转载 作者:行者123 更新时间:2023-11-30 04:56:32 26 4
gpt4 key购买 nike

我遇到了来自 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) 时,FDebug::OptionallyLogFormattedEnsureMessageReturningFalseUE4Asserts_Private::TrueFirstCallOnly 参数仅在第一次为特定的调用堆栈调用它(我在考虑每个调用堆栈,因为 TrueOnFirstCallOnly 在下一次调用时评估为 false 以确保来自相同的调用堆栈,但触发来自不同调用堆栈的确保但是不太确定)而且我不明白它是如何工作的。

正如他们在评论中所述,以某种方式将 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();
}

Live demo

诀窍是每个 labmda 表达式都有一个唯一的类型,因此它会导致 true_on_first_call 的不同实例化。即使 lambda 表达式相同([]{}[]{})它们属于不同的类型。另一方面,相同的 lambda 表达式(即第一次调用 foo 的那个和第二次调用 foo 的那个)是相同的类型。通过这种方式,每次编写 get_true_on_first_call([]{}) 时都可以获得唯一的实例化。

关于c++ - 以下代码如何工作以每次为唯一的调用堆栈唯一地实例化模板函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52441018/

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