I am getting the error in while linking my object files:
#include <cstdint>
#include <array>
enum SystemType : uint8_t { AC, DC, HCP, EFF };
template<SystemType TYPE> struct System;
template<>
struct System<AC> {
public:
static constexpr size_t number_of_sockets = 2;
static constexpr std::array<size_t, number_of_sockets> object_per_socket { { 12, 6 } };
};
I am using it as below to allocate data into a vector.
terminal->no_obj_per_system.assign(
Sytem<AC>::object_per_socket.begin(),
Sytem<AC>::object_per_socket.end());
I am using clang on mac Os.
In C++14 and earlier, static data members must have an out-of-class definition in exactly one translation unit if they are odr-used; this rule still applies to constexpr
members.
This question contains an example with references from the C++14 Standard.
If there is no out-of-class definition provided, and the variable is odr-used, then it is ill-formed with no diagnostic required, which explains why some people don't get a compilation error. To be on the safe side you should provide a definition, there's no harm doing so even in the case where the variable is not odr-used.
The definition would look like, (NOT in a header file):
constexpr std::array<size_t, System<AC>::number_of_sockets> System<AC>::object_per_socket;
In C++17 there is a new feature "inline variables", which allows variables to be defined in header files with similar semantics to inline functions, i.e. you're allowed to have multiple matching definitions across translation units, and the compiler/linker will select one as needed. constexpr
variables will be implicitly inline
, so your original code will be correct in C++17. Recent versions of gcc and clang should accept the code with -std=c++1z
flag.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With