简体   繁体   中英

How do I forward-declare a constexpr object at namespace scope?

On clang (trunk) I can forward declare an object that will later be defined with constexpr as follows:

// Fwd-declarations
struct S;
extern const S s;

// (... later) definitions
struct S {};
constexpr S s {};

Gcc 4.8 doesn't like this, telling me the forward-declaration and the definition differ in constexpr -ness. Is gcc speaking truth, or is this just a gcc bug?

I can't find any language in my copy of the C++11 standard that explicitly forbids constexpr -ness from mis-matching between a declaration and a definition, but I do see language explicitly forbidding constexpr from being used with extern (section 7.1.5), and I also see language requiring the initializer for a class-level static constexpr variable to be in the class. Also, since the utility of constexpr is significantly reduced when the definition of the variable or its type is unavailable, I think it's likely the intent is that constexpr variables must be defined (or, for static class members, initialized) when they are declared.

As a work-around, perhaps you could provide an extern alias for the variable. This would allow you to take its address, and that's the only thing I can think of that a forward-declaration would allow. For example:

// .hpp file:
struct C;
extern C const &c;

// .cpp file:
struct C {
    constexpr C() { }
};
constexpr C cc;
C const &c = cc;

Side note: I know that in C++14, they revisited/are revisiting constexpr , so it's possible that it works in Clang because it's implementing some draft spec of C++14.

The real answer is that gcc is plain wrong, clang is right. The code above should compile, and it will in gcc 4.9. Or so says this bug report .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM