lundi 2 août 2021

Instantiate class at compile time and modify at runtime

I curiously couldn't find anything on this but I want to initialize a class at compile time with constexpr. The class however should be later modifiable at runtime. In essence, the constructor of the class Light is constexpr, while other member vars are not. Additionally, the class initializes an array of member classes which are also "half constexpr / half modifiable". The following gives me various errors but I can't figure out what to change:

Code:

struct A
{
    int a;
    double b;
};

class Color
{
    std::vector<A> points_; <-- modify later

    /* const part */

    const std::string name_;
    public:
        constexpr Color(std::string name) : name_(std::move(name)) {}
};

class Light
{   
    void foo();
    int a = 5;

    /* const part */

    std::array<Color, 3> colors_ = { Color("blue"), Color("red"), Color("yellow") };
};

constexpr Light some_light; // <-- how to make this possible?

Compiling this in gcc yields the following errors:

<source>: In constructor 'constexpr Color::Color(std::string)':
<source>:19:19: error: invalid type for parameter 1 of 'constexpr' function 'constexpr Color::Color(std::string)'
   19 |         constexpr Color(std::string name) : name_(std::move(name)) {}
      |                   ^~~~~
In file included from /opt/compiler-explorer/gcc-11.1.0/include/c++/11.1.0/string:55,
                 from <source>:2:
/opt/compiler-explorer/gcc-11.1.0/include/c++/11.1.0/bits/basic_string.h:77:11: note: 'std::__cxx11::basic_string<char>' is not literal because:
   77 |     class basic_string
      |           ^~~~~~~~~~~~
/opt/compiler-explorer/gcc-11.1.0/include/c++/11.1.0/bits/basic_string.h:77:11: note:   'std::__cxx11::basic_string<char>' has a non-trivial destructor
<source>: At global scope:
<source>:32:17: error: the type 'const Light' of 'constexpr' variable 'some_light' is not literal
   32 | constexpr Light some_light; // <-- how to make this possible?
      |                 ^~~~~~~~~~
<source>:22:7: note: 'Light' is not literal because:
   22 | class Light
      |       ^~~~~
<source>:22:7: note:   'Light' has a non-trivial destructor
Compiler returned: 1

How can I make ´Light´ instantiable at compile time (if possible)?

Aucun commentaire:

Enregistrer un commentaire