Kyle
Kyle

Reputation: 21

Non-literal type cannot be used in a constant expression (C++)

Here is the definition of the class.

Class Type {
  public: 
    constexpr Type (std::string label, const std::set<int>& ids) : label_(label), ids_(ids) {}

  private:
    const std::string label_;
    const std::set<int>& ids_;
}

I want to define some const objects so that we can use as the enums. For example:

const Type A = {"type_a", {1, 2}};
const Type B = {"type_b", {3}};

But I got the following error

Non-literal type std::set<int> cannot be used in a constant expression

Any idea for how to initial the const object correctly? Suggestions for changing the definition of class are also welcome. Thanks!

Upvotes: 2

Views: 3788

Answers (2)

Humac
Humac

Reputation: 81

Simply because you can't create strings at compile time, think about it first, strings most of the time allocate memory. So what will you do about this memory allocation during compile time? You have to provide some compile time allocations, like pmr in C++20. By the way, some containers like std::array( take a look at this https://en.cppreference.com/w/cpp/header/array) can be used in compile-time contexts since they are simple enough to be constructed during compilation. Remember that the memory allocated at compile time must be released at the end of the compilation.

And also I think this question may help you a little bit better to comprehend what we have talked about it here. https://codereview.stackexchange.com/questions/272265/c20-compile-time-string-utility

Upvotes: 0

Eugene
Eugene

Reputation: 7178

If all you need is to create a const object like this

const Type A = {"type_a", {1, 2}};

i.e. an object that cannot be changed once it is initialized, then you merely need to remove constexpr from the constructor.

Upvotes: 1

Related Questions