我想知道C ++标准是否可以保证以下行为(请参见断言)?似乎它可以在最新版本的clang和gcc下工作,但是我仍然不确定它的标准定义行为或实现是否定义了它。
#include <cassert>
#include <functional>
struct test
{
using fn_ptr_t = int(*)(int);
fn_ptr_t fn_ = nullptr;
template<auto Fun>
void assign() noexcept
{
fn_ = +[](int i)
{
return std::invoke(Fun, i);
};
}
};
int fun(int i) { return i; }
int gun(int i) { return i; }
int main()
{
test t0, t1, t2;
t0.assign<&fun>();
t1.assign<&fun>();
t2.assign<&gun>();
assert(t0.fn_ == t1.fn_);
assert(t0.fn_ != t2.fn_);
return 0;
}
我发现该标准对函数指针说了以下几点:
C ++ 03 5.10 / 1 [expr.eq]:...可以比较指向相同类型的对象或函数的指针(在指针转换之后)是否相等。当且仅当两个指针都为null,都指向相同的函数或都表示相同的地址(3.9.2)时,两个相同类型的指针才会比较相等。
但是,我不确定函数指针指向lambda函数时会发生什么情况,因为每次都将lambda称为唯一对象。
没错,lambda是唯一的,这正是第二个断言通过的原因。但是它们在每次评估中并不总是不同的:
template <typename>
auto get() { return []{}; }
auto l1 = get<int>();
auto l2 = get<long>();
auto l3 = get<int>();
static_assert(std::is_same_v<decltype(l1), decltype(l2)>); // fails
static_assert(std::is_same_v<decltype(l1), decltype(l3)>); // passes
// caveat: needs C++20
l1 = l2; // no, different lambdas
l1 = l3; // ok, same lambda
在你的情况下,函数指针t0
和t1
是一样的,因为他们都是通过分配assign<&fun>
,其中拉姆达具有总是相同的类型。
由于它们具有相同的类型operator()
,因此它们具有相同的类型,因此两个函数指针都相同(它们指向相同的operator()
)。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句