一个“constexpr”函数不应该声明为“inline”。

5

通过使用 SonarLint 分析代码,我收到了一个关于以下声明的析构函数的信息(问题的标题):

class Foo
{
public:
.   // default ctor
.   // parameterized ctor
.
    inline ~Foo() = default; // dtor
.
.   // copy ctor = delete
.   // copy assignment operator = delete
.   // move ctor
.   // move assignment operator

private:
    ...
    mutable std::vector< std::vector<char> > m_Matrix;
    ...
};

以下是该消息的描述

将函数或静态成员变量声明为constexpr会使其隐式成为内联函数。

我认为此类的析构函数不能是constexprconsteval,因为它有一个类型为std::vector的非静态数据成员,所以~Foo必须在某个时刻调用delete[]来释放向量的存储空间。

那么为什么SonarLint会显示这条消息呢?是因为= default吗?任何默认的特殊成员函数都会隐式地成为constexpr吗?


6
即使不考虑constexpr,在类主体中定义的每个成员函数都是隐式地内联的。 - HolyBlackCat
1
手动定义一个空/默认析构函数几乎总是一个错误,除非您还定义了复制/移动操作。它会默默地将类的复制替换为移动,例如:https://gcc.godbolt.org/z/GTzdE9azs - HolyBlackCat
2
@digito_evo “remove it” 可能意味着“删除析构函数(默认)定义”。 - Daniel Langr
1
当您在类定义内部定义一个函数时,它会被隐式定义为内联函数。~Foo() = default; 被视为定义,因此它将自动进行内联。 - NathanOliver
2
是的,抱歉,我指的是删除默认析构函数。但是关于移动操作,如果它们只移动m_Matrix,那么它们应该被=default,并且可以选择删除已删除的复制操作,因为当您具有自定义(或默认)移动操作时,它们会自动删除。或者,如果您不介意类可复制,您可以同时删除复制和移动操作。 - HolyBlackCat
显示剩余7条评论
1个回答

5

是的:

一个显式缺省定义的函数如果没有定义为删除,只有在它是constexpr兼容的时候才能声明为constexprconsteval([special],[class.compare.default])。 第一次声明上显式缺省定义的函数是隐式内联的([dcl.inline]),如果它是constexpr兼容的则隐式成为constexpr([dcl.constexpr])。

(来自显式缺省定义函数,强调是我的。)

C++20中,因为std::vector现在可以是constexpr的,所以Foo很可能是constexpr兼容的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接