lundi 17 juillet 2017

Force in class const member of class to be evaluated at compile time

I am creating a game of Snake using SFML, and I have a concrete class SnakeGame that holds all the data members of my class, such as window size, size of a game map, color of the snake, etc. Thus, my class's internal members look like this:

class SnakeGame
{
private:
    //....
    const sf::Vector2u windowSize{400, 336};
    const sf::Color snakeColor {0, 0, 0};
    //...etc...
public:
    SnakeGame() : 
        renderWindow {sf::VideoMode{windowSize.x, windowSize.y}, /*other arguments*/ },
        snake {snakeColor, /*other arguments*/} 
        /*etc*/ 
    {}

However, this does not work and I get a window that is invisible, leading me to believe the arguments are not constructed yet. After reading another SO post, I read that const members as a class's members are not evaluated at compile time, but at runtime when the class is instantiated, and they behave otherwise in exactly the same ways as const variables. Thus, the variables windowSize and snakeColor are evaluated when I instantiate SnakeGame in main, so I cannot use them in the initializer list of my class. To try and solve this predicament, I decided to switch to static constexpr variables, but unfortunately I realized that sf::Vector<T> does not have a constexpr constructor, and neither does sf::Color. Of course, I guess I could just switch to integral types, such as static constexpr unsigned int for the window size, but eventually this becomes repetitive, especially for colors. So I decided to take another route. What I did was create another file GameData.hpp, and do this in it:

namespace gd //For game data
{
    const sf::Vector2u windowSize{400, 336};
    const sf::Color snakeColor {0, 0, 0};
    //...etc...
}

However, I do not like this solution, since even if this data is now evaluated at compile time, it is also accessible to all my classes if they include the appropriate header file, not just to SnakeGame. In this way, I feel like the internal data structure of my class is being revealed. Which leads to my question, which is: Is there a way to force const members of a class to be evaluated at compile time in a way such that these variables can be used in initializer lists with the guarantee that they will constructed?

Aucun commentaire:

Enregistrer un commentaire