Всем привет
Чувствую что туплю, потому прошу помощи - просветить.
Нужно сделать константу в классе, которая представляет из себя union. Сейчас это строка в самом низу:
static const TUnion A = TUnion(1,1);
(сорри за неинформативное имя)
Компилирую так:
$ g++ -std=c++14 -ggdb -o range range.cpp
Текущий вариант кода выдает такое:
test.cpp:74:36: error: ‘constexpr’ needed for in-class initialization of static data member ‘const TRangeLocation::TUnion TRangeLocation::A’ of non-integral type [-fpermissive]
static const TUnion A = TUnion(1,1);
^
test.cpp:74:36: error: ‘constexpr TRangeLocation::TUnion::TUnion(TPointLocation::T, TPointLocation::T)’ called in a constant expression
Что ему нужно? Или вообще так нельзя?
Я ожидаю, что если я скормлю ему две единицы, то m_range константы TRangeLocation::A будет содержать 257.
#include <iostream>
#include <iomanip>
#include <cstdint> // uint8_t
#include <type_traits>
/**
* \brief Definitions of constants for describing location of point relative of range's endpoints
*
* If was decided no not using enum since a bug in gcc: when defining bitsize of enum field, gcc emits warning: http://stackoverflow.com/questions/28401851/is-it-possible-to-specify-the-bit-width-of-an-enum-in-c11
* All constants shall have same type
* MAX shall contain maximum value
*/
class TPointLocation{ /// \todo: Rename to TPointRangeLocation
public:
typedef uint8_t T; /// To let all constants have same type
static const T LEFT_FROM = 0; /// -p-f---t---
static const T EQUAL_FROM = 1; /// ---fp--t---
static const T BETWEEN = 2; /// ---f-p-t---
static const T EQUAL_TO = 3; /// ---f---tp--
static const T RIGHT_TO = 4; /// ---f---t-p-
static const T MAX = 4; /// Maximum value of all constants. Uses for static_assert.
/// \todo: think about constexpr
};
/**
* \brief Location of one range relative to another one.
*/
class TRangeLocation{ /// \todo: Rename to TRangeRangeLocation
public:
typedef uint16_t T; /// Shall fit two TPointLocation::T
/** \brief A structure just containing location information of two endpoints of the range.
*
* Used in union to construct cummulative value.
* Shall not be a bitfield, since later will use reference to it.
* Separated because a new struct cannot be defined in the union.
*/
struct TPoints{
static_assert(std::is_integral<TPointLocation::T>::value && std::is_unsigned<TPointLocation::T>::value,"TPointLocation is expected to be an unsigned integer");
//static_assert(TPointLocation::MAX < 9,"Bitfield size in not enough to store the value");
static_assert(sizeof(T)==sizeof(TPointLocation::T)*2 ,"Size of TrangeLocation: is bigger (and thus causes ambiguity) or is not enough");
TPointLocation::T from;
TPointLocation::T to;
constexpr TPoints():from(0),to(0){};
constexpr TPoints(TPointLocation::T f, TPointLocation::T t):from(f),to(t){};
};
union TUnion{
TPoints m_points; /// It is prefered to avoid constructions like m_points.from, but this is impossible
T m_range;
constexpr TUnion():m_range(0){};
constexpr TUnion(TPointLocation::T from, TPointLocation::T to):m_points(from,to){};
} m_value;
const T &m_range = m_value.m_range; /// Convenient alias
const TPointLocation::T &m_from = m_value.m_points.from; /// Convenient alias
const TPointLocation::T &m_to = m_value.m_points.to; /// Convenient alias
TRangeLocation(){};
TRangeLocation(TPointLocation::T from, TPointLocation::T to):m_value(from,to){};
TRangeLocation& operator=(TRangeLocation &&b)
{
m_value.m_range = std::move(b.m_value.m_range);
return *this;
};
static const TUnion A = TUnion(1,1);
} x;
int main()
{
return 0;
};