LINUX.ORG.RU

с++: имеет ли смысл писать inline для методов шаблонного класса?

 


0

3

Имеет ли смысл писать inline для методов шаблонного класса и для шаблонных функций? Это что-либо оптимизирует или меняет для компилятора?

===========================

По результатам обсуждений пришел к выводу, что inline для шаблонных функций и для методов с телом в объявлении класса по сути лишний мусор в коде.



Последнее исправление: cetjs2 (всего исправлений: 3)

inline означает «допустимо несколько определений функции», к инлайнингу методов и функций это уже непосредственного отношения не имеет. Если ты объявляешь тело метода прямо в декларации класса, метод уже является inline, даже если явно это не указано.

i-rinat ★★★★★★★★★★★★★★★★★★★★
()
Ответ на: комментарий от i-rinat

Согласно русскоязычным описаниям, inline означает встраиваемые функции. «допустимо несколько определений функции» эта фраза мне не понятна и откуда она берется.

На моем практическом опыте inline означает, будет ли функция сидеть в объектнике, или будет каждый раз браться из хедера и встраиваться в место вызова.

И остается вопрос, почему это ключевое слово может применяться к методам описанным непосредственно в классе, или к шаблонным сущностям. И при этом без каких-либо предупреждений даже со стороны компилятора или редакторов.

На лишние «;» редактор Qt уже давно ругается. А на лишние inline молчит. Может есть какой скрытый смысл?

victor79
() автор топика
Ответ на: комментарий от i-rinat

И так же получается, что функции cо словом static (хоть оно и устаревшее), имеет во многом похожий смысл inline, поскольку компилятор уже сам решает встраивать их или нет, и в объектник их объявления так же не попадают.

victor79
() автор топика
Ответ на: комментарий от victor79

«допустимо несколько определений функции» эта фраза мне не понятна и откуда она берется.

Например, здесь: https://en.cppreference.com/w/cpp/language/inline

На моем практическом опыте inline означает, будет ли функция сидеть в объектнике, или будет каждый раз браться из хедера и встраиваться в место вызова.

Я подозреваю, что у inline-функции можно взять адрес, так что функция может и «сидеть в объектнике».

почему это ключевое слово может применяться к методам описанным непосредственно в классе

Потому что inline это такая фича языка, а не свойство компилятора. Компилятор может использовать спецификатор inline как подсказку, а может и не использовать. Требований об обязательном инлайнинге нет.

i-rinat ★★★★★★★★★★★★★★★★★★★★
()
Ответ на: комментарий от victor79

static

в объектник их объявления так же не попадают

Потому что объявляя функцию static, ты требуешь, чтобы область видимости ограничивалась текущей единицей трансляции.

имеет во многом похожий смысл inline

Наверное, можно и так говорить. Но смысл всё же разный.

i-rinat ★★★★★★★★★★★★★★★★★★★★
()

Для шаблонов inline не имеет смысла, за исключением их полных специализаций.

PRN
()
Ответ на: комментарий от xaizek

Хм. А зачем экспортировать в глобальное пространство имён? Можно же прятать в безымянном namespace.

i-rinat ★★★★★★★★★★★★★★★★★★★★
()
Ответ на: комментарий от i-rinat

Для типов static недоступен и там только так. А для функций и переменных можно static.

xaizek ★★★★★★★★★★★★★★★
()

Получается, что никакого скрытого смысла нет? И использование этого для описанных случаев это лишний мусор в коде?

victor79
() автор топика

inline может использоваться в имплементации если он необходим

и имплементация находиться отдельно от декларации

anonymous
()
Ответ на: комментарий от victor79

«допустимо несколько определений функции» эта фраза мне не понятна и откуда она берется.

Почитай Шаблоны C++ Справочник разработчика (Дуглас Грегор, Дэвид Вандевурд, и Николаи Джосаттис).

rumgot ★★★★★★★★★
()
Ответ на: комментарий от victor79

Есть заголовочный файл template.h:

#ifndef TEMPLATE_H
#define TEMPLATE_H

#include <iostream>
template <typename T> auto f(T t) {
  std::cout << "Base template " << t << std::endl;
}
template <> inline auto f(int t) {
  std::cout << "Full specialization for int " << t << std::endl;
}
// Вместо полной специализации можно использовать простую функцию:
// inline void f(int t) {
//   std::cout << "Non template function " << t << std::endl;
// }
#endif // TEMPLATE_H

При попытке включить его в две единицы трансляции без inline будет ошибка:

multiple definition of ...

Может возникнуть вопрос: почему первичный шаблон не помеченный ключевым словом inline может быть включен в разные единицы трансляции без ошибок?: потому что для них разрешено иметь иметь определения в разных единицах трансляции, а для полной специализации этого шаблона это не разрешено без inline.

Кстати сказанное справедливо и для функций-членов класса, которые определены в заголовочном файле (в объявлении класса (такие функции-члены объявлены inline неявно) или за его пределами (такие нужно объявлять inline явно)):

class A {
public:
  static inline void f();
};

void A::f() { std::cout << "A::f()" << std::endl; }
rumgot ★★★★★★★★★
()
Последнее исправление: rumgot (всего исправлений: 2)
Ответ на: комментарий от rumgot

такие функции-члены объявлены inline неявно

Вы в своём примере inline не туда поставили, вводите подрастающее поколение в заблуждение ;)

bugfixer ★★★★★
()
Ответ на: комментарий от victor79

И так же получается, что функции cо словом static (хоть оно и устаревшее), имеет во многом похожий смысл

Уже выше абсолютно правильно ответили что ни в одном глазу не устаревшее.

Получается, что никакого скрытого смысла нет? И использование этого для описанных случаев это лишний мусор в коде?

Неправда. Просто довольно часто вещи «implicitly inline». В качестве разминки предлагаю подумать могут ли virtual methods ever be inlined. И как оно вообще работает для [implicitly] inline virtuals (что в vtable втыкать будем, где outline body генерятся, и как потенциальные конфликты разруливаются). На интервью, кстати, люблю спрашивать - многое сразу становится понятно ;)

bugfixer ★★★★★
()
Последнее исправление: bugfixer (всего исправлений: 2)
Ответ на: комментарий от i-rinat

Потому что объявляя функцию static, ты требуешь, чтобы область видимости ограничивалась текущей единицей трансляции.

Не путай область видимости и linkage.

anonymous
()
Ответ на: комментарий от bugfixer

Согласен. Ошибся. Конечно ключевое слово inline применительно к методу класса должно находится в определении метода.

rumgot ★★★★★★★★★
()
Последнее исправление: rumgot (всего исправлений: 1)
Ответ на: комментарий от i-rinat

Ну, например, в LLVM coding style запрещает анонимные неймспейсы и требует статическую функцию. То есть

namespace {
  void EnlargePenis() {}
} // anon ns

ревью не пройдёт.

HugeCoreDump
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.