问题
I try to find a way in C++17 to shorten following function calls:
GetCurrentContext()->GetEntityManager()->CreateEntity();
maybe to something like:
EM()->CreateEntity();
I tried a function pointer, but this is only valid for static functions:
constexpr auto &EM = GetContext()->GetEntityManager;
// error: reference to non-static member function must be called;
Is there a better solution than using a Macro?
#define EM GetContext()->GetEntityManager
When using an inline function call, i'm afraid, that the compiler will ignore this and i have an unnessessary overhead:
inline EntityManager* EM() { return GetCurrentContext->GetEntityManager(); }
Also this seems to be the wrong way to go, because i'm looking for an alias, not for another function to define.
EDIT:
Every Context has an EntityManager and the current Context can change during runtime. So i'm really looking for an alias, not for a const pointer to what the function returns.
UPDATE:
I found this Question. With return type auto, the inline function becomes independet from the original return type. Even if the original function will get changed in future, the alias need not be touched again. And with trust in compiler optimization this will really become a real alias.
So i think (In consideration of the answers and comments) the best solution is to do the following:
inline decltype(auto) EM() { return GetCurrentContext()->GetEntityManager(); }
回答1:
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 }
This can be simplified, and I will leave it upto you. I'm just illustrating how to alias, (without even knowing the types).
you can do something similar with function pointers and then alias as many steps as you like and return at whichever stage you want.
The idea is of having a lambda inside another lambda, this way you do not have to worry that the object changed since it is going to do forwarding not store the object. This way all functions in the chain are called at each invocation of the lamba as it returns the inner lambda that you invoke.
If you think carefully, you can store the function, you don't need to do y(a), it was written in a rush.
回答2:
auto const p = GetCurrentContext()->GetEntityManager();
p->CreateEntity();
Under reasonable assumptions of what the code is about.
There is also an assumption, implicit in your question, that the result from GetEntityManager
will be the same in each call in the original code.
来源:https://stackoverflow.com/questions/50401618/c-shorten-subsequent-function-calls