Как разместить пользовательский литерал внутри класса constexpr того же типа в C ++? - PullRequest
0 голосов
/ 24 августа 2018

Я хочу реализовать свой собственный класс строкового литерала Literal и оператор:

constexpr Literal operator""_s(const char* str, size_t size);

class Literal {
  friend constexpr Literal operator"" _s(const char*, size_t);

  constexpr Literal(const char* str, size_t size);

  const char* str = nullptr;
  const size_t size = 0u;
};

Затем я хочу разместить пустой литерал внутри моего класса:

class Literal {
  …
  static constexpr const Literal empty = ""_s;
  …
};

КакОжидаемый компилятор отказывается от такой конструкции, потому что на этом этапе класс неполон.Также я полагаю, что это технически должно быть возможно, так как компилятору просто нужно где-то поместить пару char* str = nullptr и size_t size = 0 для литерала empty и назначить ее во время компиляции статическому экземпляру моего класса.

Есть ли какой-то «трюк» для достижения такого условия, как: auto new_literal = Literal::empty;?

Ответы [ 2 ]

0 голосов
/ 25 августа 2018

Есть ли какой-то "трюк" для достижения этого условия, например: auto new_literal = Literal::empty;?

Вы можете добавить статическую функцию-член,

class Literal {
  // …
  static constexpr Literal empty() { return ""_s; }
  // …
}

ииспользуйте его как

constexpr auto new_literal = Literal::empty();

Однако обратите внимание, что

static_assert("" != nullptr);
static_assert(""[0] == '\0');
0 голосов
/ 24 августа 2018

Нет, такого трюка нет.Этот пример ничем не отличается от

struct X;
constexpr X getx();

struct X {
    static constexpr X x = getx();

};

Неполные классы не могут использоваться в качестве переменных constexpr, поскольку, согласно стандарту,

Спецификатор constexpr, используемый в объявлении объекта, объявляетобъект как постоянныйТакой объект должен иметь литеральный тип и должен быть инициализирован.

На этом этапе компилятор даже не знает, является ли тип литеральным типом, поэтому он не может принять неполный класс.

...