Struct是非文字类型

时间:2016-04-26 11:22:51

标签: c++ c++11 constexpr

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

constexpr static常量定义无法编译:

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

但是根据http://en.cppreference.com/w/cpp/concept/LiteralTypeconst rgb_color应该是文字类型,因为它只有文字类型作为数据成员(std::uint8_t)和constexpr构造函数。 / p>

为什么代码不能编译?

此外,是否有必要在constexpr static文件中定义.cc成员,例如

constexpr rgb_color rgb_color::black;

4 个答案:

答案 0 :(得分:16)

这不起作用,因为你正在实例化一个尚未完全声明的类型(你尚未到达右括号和分号,所以rgb_color仍然是一个不完整的类型)。

你可以通过在类中声明你的常量来解决这个问题,可能在他们自己的命名空间中:

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

答案 1 :(得分:3)

您应该能够将blackwhite转换为static constexpr个功能 - 即。这是"命名构造函数idiom的一个例子。"

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() { return rgb_color(0, 0, 0); }
    constexpr static rgb_color white() { return rgb_color(255, 255, 255); }
};

答案 2 :(得分:2)

为什么不呢?

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

    static const rgb_color black;
    static const rgb_color white;
};

const rgb_color rgb_color::black {0, 0, 0};
const rgb_color rgb_color::white {255, 255, 255};

答案 3 :(得分:1)

要更新@zdf的答案,以下代码可用于C ++ 17:

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

    static const rgb_color black;
    static const rgb_color white;
};

constexpr rgb_color rgb_color::black {0, 0, 0};
constexpr rgb_color rgb_color::white {255, 255, 255};

int main() {
    constexpr auto yes = rgb_color::black;
}

链接到测试用例:https://godbolt.org/z/Q6FP_t