Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Struct is non-literal type

struct rgb_color {
    constexpr rgb_color(std::uint8_t nr, std::uint8_t ng, std::uint8_t nb) :
        r(nr), g(ng), b(nb) { }

    std::uint8_t r; // red
    std::uint8_t g; // green
    std::uint8_t b; // blue

    constexpr static rgb_color black = rgb_color(0, 0, 0);
    constexpr static rgb_color white = rgb_color(255, 255, 255);
};

The constexpr static constant definitions fail to compile:

constexpr variable cannot have non-literal type 'const rgb_color'

However according to http://en.cppreference.com/w/cpp/concept/LiteralType, const rgb_color should be a literal type, because it has only literal types as data members (std::uint8_t), and the constexpr constructor.

Why does the code not compile?

Also, is it necessary to define the constexpr static members in a .cc file, like

constexpr rgb_color rgb_color::black;
like image 564
tmlen Avatar asked Apr 26 '16 11:04

tmlen


People also ask

What is non literal type in C++?

it is an aggregate type or has at least one constexpr constructor or constructor template that is not a copy or move constructor, and. all of its non-static data members and base classes are of non-volatile literal types.

What is a literal type?

Literal types let you indicate that an expression is equal to some specific primitive value. For example, if we annotate a variable with type Literal["foo"] , mypy will understand that variable is not only of type str , but is also equal to specifically the string "foo" .

Is constexpr a const?

A constexpr variable must be initialized at compile time. All constexpr variables are const . A variable can be declared with constexpr , when it has a literal type and is initialized. If the initialization is performed by a constructor, the constructor must be declared as constexpr .

What can be constexpr?

constexpr specifies that the value of an object or a function can be evaluated at compile-time and the expression can be used in other constant expressions.


1 Answers

This doesn't work, because you are instantiating a type that is not fully declared yet (you have not reached the closing brace and semicolon yet, so rgb_color is still an incomplete type).

You can work around this by declaring your constants out of the class, maybe in their own namespace:

namespace rgb_color_constants {
    constexpr static rgb_color black = rgb_color(0, 0, 0);
    constexpr static rgb_color white = rgb_color(255, 255, 255);
}
like image 139
rems4e Avatar answered Sep 23 '22 06:09

rems4e