Why cant i use alias type for constructing? C++

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)

>Solution :

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)>

Godbolt link

Leave a Reply