Potatoswatter
Potatoswatter

Reputation: 137910

constexpr global of class type

My understanding is that constexpr globals of class type are all but unusable because

Is this all correct? Is there any way to have a constexpr global of class type without wrapping it in an inline function?

Upvotes: 15

Views: 1240

Answers (1)

TemplateRex
TemplateRex

Reputation: 70556

Global constexpr variables can ODR-safely be defined in headers using a bit of macro magic and the proverbial extra level of indirection

#define PP_GLOBAL_CONSTEXPR_VARIABLE(type, var, value)                   \
namespace var##detail {                                                  \
template<class = void>                                                   \
struct wrapper                                                           \
{                                                                        \
     static constexpr type var = value;                                  \
};                                                                       \
template<class T>                                                        \
constexpr type wrapper<T>::var;                                          \
}                                                                        \
namespace {                                                              \
auto const& var = var##detail::wrapper<>::var;                           \
}

The macro provides a reference inside an unnamed namespace to an object instance in an implementation class template.

Each object in an unnamed namespace inside a header generates a unique instance in every translation unit that includes its header. Furthermore, to prevent ODR violations, it is important that the objects in e.g. multiple instantiations of a function template are the same.

However, for references it doesn't matter that they have a different identity; as long as they refer to the same object instance in an implementation class template.

You can wrap this macro in a header and safely include it in many TUs without a problem.

See the following discussion on the Boost mailinglist for more details: http://lists.boost.org/Archives/boost/2007/06/123380.php

Upvotes: 1

Related Questions