C ++ Сократить последующие вызовы функций - PullRequest
0 голосов
/ 18 мая 2018

Я пытаюсь найти способ в C ++ 17 сократить следующие вызовы функций:

GetCurrentContext()->GetEntityManager()->CreateEntity();

может быть что-то вроде:

EM()->CreateEntity();

Я попробовал указатель на функцию, но это допустимо только для статических функций:

constexpr auto &EM = GetContext()->GetEntityManager;
// error: reference to non-static member function must be called;

Есть ли лучшее решение, чем использование макроса?

#define EM GetContext()->GetEntityManager

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

inline EntityManager* EM() { return GetCurrentContext->GetEntityManager(); }

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

EDIT:

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

UPDATE:

Я нашел этот Вопрос. С типом возврата auto встроенная функция становится независимой от исходного типа возврата. Даже если исходная функция будет изменена в будущем, псевдоним больше не нужно трогать. А с уверенностью в оптимизации компилятора это действительно станет настоящим псевдонимом.

Так что я думаю (с учетом ответов и комментариев) лучшее решение - сделать следующее:

inline decltype(auto) EM() { return GetCurrentContext()->GetEntityManager(); }

Ответы [ 2 ]

0 голосов
/ 18 мая 2018
  1 #include <iostream>
  2 #include <string>
  3
  4 using namespace std;
  5
  6 class A {
  7   public:
  8    std::string x;
  9    A () {
 10      x += "a";
 11    }
 12
 13    std::string ax() {  //imagine this to be some object.
 14     return x;
 15    }
 16 };
 17
 18 int main () {
 19   A a;
 20   auto y = [] (decltype(a)& a) {
 21     return [&a] () {
 22       return a.ax(); //imagine this to be a big chain like yours. I just wanted to give you a working example, so I'm not doing your calls.
 23     };
 24   };
 25   std::cout << y(a)().at(0) << std::endl; //TADA!! this works
 26   return 1;
 27 }

Это можно упростить, и я оставлю это вам.Я просто иллюстрирую, как создать псевдоним (даже не зная типов).

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

Идея состоит в том, чтобы иметь лямбду внутри другой лямбды , таким образом, вам не нужно беспокоиться о том, что объект изменился, так как он будет выполнять пересылку, не сохраняя объект.Таким образом, все функции в цепочке вызываются при каждом вызове lamba, поскольку он возвращает внутреннюю лямбду, которую вы вызываете.

Если вы тщательно продумаете, вы можете сохранить функцию, вам не нужно делать у (а) , это было написано в спешке.

0 голосов
/ 18 мая 2018
auto const p = GetCurrentContext()->GetEntityManager();
p->CreateEntity();

При разумных предположениях о коде.

Существует также предположение, неявное в вашем вопросе, что результат из GetEntityManager будет одинаковым при каждом вызове в исходном коде.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...