constexpr(expr) - альтернативный синтаксис "constexpr!" для функции и const(auto)

Данил Луценко
Данил Луценко

Позволяет явно указывать возможность исполнения функции на этапе компиляции добавляя гибкость для мета-программирования, и имеет более привычный синтаксис (подобный уже используется для noexcept(expr) и decltype(expr)) нежели "constexpr!".

Например,

template<typename T>
constexpr T ConstValue = static_cast<T>(0x1'000'000);

constexpr(false == false) int A() { return 5; }
constexpr(true == false) int B() { return 5; }

static_assert(A() == 5); //ОК, функция помечена как constexpr(true)
static_assert(B() == 5); //ошибка, функция не может использоваться на этапе компиляции

int main()
{
    assert(A() == 5); //ошибка, функция A не может вызываться на этапе исполнения
    assert(B() == 5); //ОК
}

 

Предлагаю так же разрешить constexpr(auto), который ведет себя как и текущий constexpr
constexpr(auto) int A() { return 5; }
В будущем предлагаю помечать неявно как constexpr(auto) любую inline функцию или метод, которому может примениться constexpr, что позволит  частично использовать уже написанный код на этапе исполнения без потери совместимости с существуещим кодом использующим constexpr.

Почему для constexpr(false) не задействовать старый синтаксис вместо constexpr(auto)?! Предлагаю в будущем добавить в объявление функции const(expr)/const(auto), где const(auto) генерирует 2 функции, одна с const модификатором, вторая без. Ровно как и constexpr(auto), который генерирует 2 функции, одну для этапа компиляции, вторую для исполнения.

const(auto) может использоваться в следующем случае

class A {
    std::string m;
public:
    auto& get_m() const(auto) { return m; }
};

что аналогично следующему коду
class A {
    std::string m;
public:
    auto& get_m() { return m; }
    auto& get_m() const { return m; }
};

Как и в случае с constexpr(auto), предлагаю помечать неявно const(auto) все inline методы, которые могут быть помечены как const, что избавит от забытых const в библиотечном коде без потери совместимости со старым кодом.
Возможность явно указывать константность в const с помощью условного выражения этапа компиляции позволит управлять константностью метода исходя из параметров шаблона и для явного описания константности в интерфейсе.

-1
рейтинг
2 комментария
Данил Луценко

Дополнительно предлагаю разрешить перегрузку функции для контекстов времени компиляции и исполнения, как альтернатива магической std::is_constant_evaluated

constexpr(false) int atoi(const char *S);
constexpr(true) int atoi(const char *S) { /*...*/ }
static_assert(atoi("5") == 5); //Вызывает constexpr(true) int atoi(const char *S)
int main()
{
    assert(atoi("5") == 5); //Вызывает constexpr(false) int atoi(const char *S)
}

тогда constexpr(auto) можно сделать лучше:

Например пусть следующий код
constexpr(auto) int atoi(const char *c)
{
    return std::atoi(c);
}
аналогичен следующему коду
constexpr(false) int atoi(const char *c)
{
    return std::atof(c);
}
т.к. нет перегрузки функции std::atoi c constexpr(true)


И
consexpr(auto) int atoi(const char *S) {

   int result = 0;
   while (*S) {
      result = result * 10 + (*S - '0');
      ++S;
   }
   return result;
}
аналогичен следующему, 
consexpr(false) int atoi(const char *S) {
   int result = 0;
   while (*S) {
      result = result * 10 + (*S - '0');
      ++S;
   }
   return result;
}
consexpr(true) int atoi(const char *S) {
   int result = 0;
   while (*S) {
      result = result * 10 + (*S - '0');
      ++S;
   }
   return result;
}
т.к. функция может быть выполнена на этапе компиляции

Данил Луценко
Fihtangolz

constexpr! <- давайте без ! как нибудь constexpr_hard 

Fihtangolz
Другие идеи
Группа создана, чтобы собирать предложения к стандарту C++, организовывать их внутренние обсуждения, помогать готовить их для отправки в комитет и защищать на общих собраниях в рабочей группе по С++ Международной организации по стандартизации (ISO).
Все предложения