I have a Class called SceneManager
with a method update that when the exit
flag is true
it switches the current scene to the using next = nextScene
, but i don't know why it doesn't work, and the compiler isn't helping much.
I reproduced the problem in this compiler explorer space Link to Compiler Explorer
My SceneManager
looks like this
template <typename T>
concept SceneType = (std::is_base_of_v<Scene, T> and !std::same_as<T, Scene>);
template <typename T, typename... U>
concept AnyOf = (std::same_as<T, U> || ...);
template <SceneType... Scenes>
struct SceneManager {
SceneManager() {}
template <AnyOf<Scenes...> T>
void change_scene() {
m_current_scene = T();
}
void update_scene() {
std::visit(
[this](auto&& val) {
if (val.exit) {
val.on_exit();
change_scene<decltype(val)::next>();
return;
}
val.on_update();
},
m_current_scene);
}
std::variant<Scenes...> m_current_scene;
};
My FirstScene
is like this
class FirstScene : public Scene {
public:
using next = SecondScene;
void on_init();
void on_update();
void on_exit();
};
Note that if i hardcode it like this it works
void update_scene() {
std::visit(
[this](auto&& val) {
using next = SecondScene;
if (val.exit) {
val.on_exit();
change_scene<next>();
return;
}
val.on_update();
},
m_current_scene);
}
I've tried using:
- public accesors
- typedefs
- hardcoding it (this works but losses the generic sense)
CodePudding user response:
val
is an lvalue reference, so decltype(val)
is FirstScene &
, not FirstScene
. You also need to specify the dependant name next
is a type.
error: type 'decltype(val)' (aka 'FirstScene &') cannot be used prior to '::' because it has no members
The full change is decltype(val)
to typename std::remove_reference_t<decltype(val)>