Рассмотрим заголовочный файл:
class T
{
private:
int const ID;
public:
explicit T(int const ID_) noexcept : ID(ID_) {}
int GetID() const noexcept { return ID; }
};
или, альтернативно:
class T
{
private:
int const ID;
public:
explicit T(int const ID_) noexcept;
int GetID() const noexcept;
};
inline T::T(int const ID_) noexcept : ID(ID_) {}
inline int T::GetID() const noexcept { return ID; }
В мире до модулей эти заголовки могут быть текстуально включены в несколько TU без нарушений ODR. Кроме того, поскольку задействованные функции-члены относительно малы, компилятор, скорее всего, будет «встраивать» (избегать вызовов функций при использовании) этих функций или даже вообще оптимизировать некоторые экземпляры T
.
В недавнем отчете о встрече, на которой был закончен C++20 , я мог прочитать следующее утверждение:
Мы разъяснили значение
inline
в интерфейсах модулей: цель состоит в том, чтобы тела функций, которые не объявлены явноinline
, не были частью ABI модуля, даже если эти тела функций появляются в интерфейсе модуля. Чтобы дать авторам модулей больший контроль над своим ABI, функции-члены, определенные в телах классов в интерфейсах модулей, больше не являются неявноinline
.
Я не уверен, что не ошибся. Означает ли это, что в мире модулей, чтобы компилятор мог оптимизировать вызовы функций, мы должны аннотировать их как inline
, даже если они определены в классе?
Если да, то будет ли следующий интерфейс модуля эквивалентен приведенным выше заголовкам?
export module M;
export
class T
{
private:
int const ID;
public:
inline explicit T(int const ID_) noexcept : ID(ID_) {}
inline int GetID() const noexcept { return ID; }
};
Несмотря на то, что у меня все еще нет компилятора с поддержкой модулей, я хотел бы начать использовать inline
, когда это уместно, чтобы свести к минимуму рефакторинг в будущем.