I'm writing a simple game with Entity Component System. One of my components is NativeScriptComponent
. It contains the instance of my script. The idea is that I can create my NativeScriptComponent
anytime and then Bind
to it any class implementing Scriptable
interface. After that my game's OnUpdate function will automatically instantiate all scripts in my game and will call their OnUpdate function.
My scripts can have their own, different constructors so I need to forward all the arguments to them when I bind my script.
Consider the following code:
#include <iostream>
#include <memory>
#include <functional>
using namespace std;
struct Scriptable
{
virtual void OnUpdate() {};
};
struct MyScript : Scriptable
{
MyScript(int n) : value(n) {}
void OnUpdate() override {cout << value;}
int value;
};
struct NativeScriptComponent
{
unique_ptr<Scriptable> Instance;
function<unique_ptr<Scriptable>()> Instantiate;
template<typename T, typename ... Args>
void Bind(Args&&... args)
{
// (A)
Instantiate = [&args...]() { return make_unique<T>(forward<Args>(args)...); };
// (B) since C++20
Instantiate = [...args = forward<Args>(args)]() { return make_unique<T>(args...); };
}
};
int main()
{
NativeScriptComponent nsc;
nsc.Bind<MyScript>(5);
// [..] Later in my game's OnUpdate function:
if (!nsc.Instance)
nsc.Instance = nsc.Instantiate();
nsc.Instance->OnUpdate(); // prints: 5
return 0;
}
1) What is the difference between option A and B
Instantiate = [&args...]() { return make_unique<T>(forward<Args>(args)...); };
vs
Instantiate = [...args = forward<Args>(args)]() { return make_unique<T>(args...); };
Why can't I use
forward<Args>(args)
insidemake_unique
in option B?Are both A and B perfectly-forwarded?