Почему нельзя создать constexpr std::error_category, ведь у этого класса есть constexpr конструктор?

Рейтинг: 0Ответов: 3Опубликовано: 09.06.2023

std::error_category имеет constexpr конструктор, но является абстрактным классом. Следовательно, его потомки не могут быть созданы constexpr. Зачем тогда конструктор error_category constexpr?

Ответы

▲ 1Принят

Вот посмотрите эти ссылки объясняют почему

https://github.com/microsoft/STL/issues/1116

https://www.cppstories.com/2021/constexpr-virtual/

▲ 3

Ну, например, в VC++ запросто можно...

#include <string>
#include <iostream>
#include <iomanip>

using namespace std;

class concrete: public std::error_category
{
public:
    constexpr concrete():std::error_category(){}
    const char* name() const noexcept { return "concrete"; }
    std::string message( int ) const { return "concrete"s; };
};

int main()
{
    constexpr concrete c;
}
▲ 1

Для constexpr нужен "Literal Type"

A constexpr specifier used in an object declaration declares the object as const. Such an object shall have literal type and shall be initialized.

https://eel.is/c++draft/dcl.constexpr#6

A type is a literal type if it is:
-- a possibly cv-qualified class type that has all of the following properties:
it has a constexpr destructor ([dcl.constexpr]),
all of its non-static non-variant data members and base classes are of non-volatile literal types, and
has at least one constexpr constructor

https://eel.is/c++draft/basic.types#general-10

а у error_category как не constexpr деструктор https://eel.is/c++draft/syserr.errcat.overview

  class error_category {
  public:
    constexpr error_category() noexcept;
    virtual ~error_category();

поэтому её объект не может быть constexpr.

Однако можно использовать constinit.