重新声明显式默认的比较运算符使其未定义

问题描述 投票:0回答:1

在下面的程序中,

struct A
有默认的友元相等比较运算符,再次重新声明它以获取函数的指针
(&operator==)

struct A {
    friend constexpr bool operator ==(const A &, const A &) noexcept = default;
};

static_assert( A{} == A{} ); //if this line is removed the program fails
constexpr bool operator ==(const A &, const A &) noexcept;
static_assert( (&operator==)( A{}, A{} ) );

所有主要编译器(GCC、Clang、MSVC)都适合该程序。在线演示:https://gcc.godbolt.org/z/dhcd8esKn

但是,如果删除带有

static_assert( A{} == A{} );
的行,则相同的编译器将开始拒绝带有错误的程序:

错误:在定义之前使用了“constexpr bool operator==(const A&, const A&)”

注意:未定义的函数“operator==”不能在常量中使用

注意:失败是由于调用未定义的函数或未声明“constexpr”的函数导致的

您能否解释一下为什么上述程序仅在

static_assert( A{} == A{} );
重新声明之前存在
operator==
才有效?

c++ language-lawyer c++20 friend comparison-operators
1个回答
0
投票

只要没有在任何地方使用比较运算符函数,它就没有定义。这意味着获取它的地址是行不通的。

§11.11.1 默认比较运算符函数

C 类的比较运算符函数在其第一个声明中默认且未定义为已删除,当使用 odr 或需要常量求值时,会隐式定义该函数。

线路

static_assert( A{} == A{} );

强制编译器为其生成定义,这是在尝试获取其地址时需要的。

© www.soinside.com 2019 - 2024. All rights reserved.