I have this snippet of code I was testing today:
#include <iostream>
struct Literal {
constexpr operator int() const { return 0; }
};
struct Class {
constexpr static const Literal field0 = Literal();
};
int main(void) {
std::cout << "Class::field0: " << Class::field0 << std::endl;
return 0;
}
It compiles without errors (G++ 6.2.1), but unfortunately I get a link error when generating the executable:
/tmp/ccao6eTy.o: In function `main':
test-constexpr-static-field.cpp:(.text+0xa): undefined reference to `Class::field0'
collect2: error: ld returned 1 exit status
[Finished in 0.3s with exit code 1]
Reading this page I see this explanation:
If a static data member of LiteralType is declared constexpr, it must be initialized with an initializer in which every expression is a constant expression, right inside the class definition (...).
Then I went for the definition of what is a LiteralType, and I saw that:
A literal type is any of the following:
- possibly cv-qualified class type that has all of the following properties:
- has a trivial destructor,
- is either
- an aggregate type,
- a type with at least one constexpr (possibly template) constructor that is not a copy or move constructor,
- a closure type (since C++17)
- all non-static data members and base classes are of non-volatile literal types.
Is it the case that Literal
does not conform to a LiteralType
? As I see it, it has a trivial constructor, and even has no internal state to avoid any troublesome issue with aggregate types or non-static fields on a literal type.
But considering it does conform (primarily because the program compiled without errors), why the link-time error? Is that a G++ bug, perhaps?
Aucun commentaire:
Enregistrer un commentaire