добавить constexpr как модификатор для аргументов функции

Юра Левченко
Юра Левченко

Расмотрим небольшой пример: 
test(a, 0);
test(a, 1);
test(a, 2);

int test( int a, constexpr int flag )
{
 switch( flag )
 {
   case 0:
     return a + 1;
   case 1:
     return a - 1;
   case 2:
     return -a;
   default:
     return 0;
 }
}

если второй параметр задать как constexpr, то можно на этапе компиляции создать 3 функции, по аналогии
test<0>(a);
test<1>(a);
test<2>(a);

template<int flag>
int test( int a )
{
 switch( flag )
 {
   case 0:
     return a + 1;
   case 1:
     return a - 1;
   case 2:
     return -a;
   default:
     return 0;
 }
}
20
рейтинг
13 комментариев
Antervis

и заодно перегрузку по constexpr'ness аргументов, а-ля

bool foo(int i) {
    return true;
}
bool foo(constexpr int i) {
    return false;
}

foo(1); // false
int i;
foo(i); // true

Такое вроде рассматривалось еще к включению в с++11, но комитет решил что сильно многословно получается

Antervis
yndx-antoshkka

Antervis, любая модификация правил перегрузок в 99.999% случаев ведёт к отклонению предложения. Так что лучше подобное не добавлять, и сосредоточиться на базовом функционале.

yndx-antoshkka
Обновлено 
Antervis

yndx-antoshkka, речь же идет не об изменении а о дополнении правил перегрузок. Никакой существующий код в таком случае не пострадает.

Вообще, не хватает языку встроенной семантики pure функций, вот только приделать её походу уже не получится

Antervis
Обновлено 
yndx-antoshkka

Antervis, описание правил Overload resolution занимает 21 страницу. Удачи с правками ;)

yndx-antoshkka
WPMGPRoSToTeMa

Antervis, я думаю куда разумнее будет ввести какой-нибудь `maybe_constexpr` (или `maybe_const`), правда нужен ещё какой-нибудь магический механизм в виде `constexpr bool std::is_constant(maybe_constexpr const auto& x)`. В принципе `constexpr` и `maybe_constexpr` параметры уже можно эмулировать с помощью аргументов завёрнутых в лямбды и `__builtin_constant_p` (или другими хаками) для проверки на константность https://godbolt.org/z/Oysrwe. Но с такой эмуляцией конечно проблема в том, что на каждый call-site инстанциируется новый шаблон.

WPMGPRoSToTeMa
Обновлено 
yndx-antoshkka

Эта идея обсуждалась, и одна из подгруп была сильно против того, чтобы функция в некоторых случаях неявно становилась шаблонной функцией.

Идея бузусловно стоящая, но надо придумать какой-то аргумент, чтобы успокоить одну из подгруп. Возможно что с недавно принятым terse syntax для концептов (аля void foo(auto SemiRegular val); ), комитет будет не сильно против.

Вообще, основное преимущество подобных аргументов - это возможность делать проверки на этапе компиляции в тех местах, где раньше были только runtime:

int array<int>::at(constepxr usinged index) const {
   try_static_assert(index < size(); std::range_error{"out of range"});
   return __data[index];
}
yndx-antoshkka
Юра Левченко

yndx-antoshkka, большое спасибо, за ответ! Смотря на тенденцию развития, мне тоже показалось что уже пора вводить такую возможность. Я думаю многие будут благодарны если Вы все таки с второй попытки протолкнете это предложение ;)

Юра Левченко
Юра Левченко

yndx-antoshkka, Добрый день, а хотел бы еще спросить, есть ли возможность как то почитать прошлые отзывы? Ну и совсем наглость, как-то быть подписаным на ответы (ридонли) нового запроса, зарание спасибо!

Юра Левченко
WPMGPRoSToTeMa

Кстати, а как это будет сочетаться с эмуляцией именованных аргументов с помощью designated initializers?

WPMGPRoSToTeMa
Юра Левченко

WPMGPRoSToTeMa, А можно подробней? Я просто не помню что бы было принято designated initializers для аргументов функций.

Юра Левченко
WPMGPRoSToTeMa

Юра Левченко,

struct Args {
  int a;
  double b;
  char c;
};

void f(Args);

f({.a = 42, .b = 13.37, .c = 'x'});
WPMGPRoSToTeMa
Обновлено 
Юра Левченко

WPMGPRoSToTeMa, Но здесь у нас один аргумент Args и то что мы передаем это неявное конструирование данного объекта перед тем как передать его в функцию. В данном случае если мы объявим Args как "возможный" constexpr то тогда если все "аргументы" передались как константы то и args будет константный

Юра Левченко
Обновлено 
Виктор Губин

У GCC и clang вместо этого введена встроенная функция __builtin_constant_p, в итоге можно делать что-то вроде

constexpr inline __attribute__((always_inline) int foo(int a) noexcept {
     // need inline
    if( __builtin_constant_p(a) ) {
        // some constexpr alg
        return 0;
    } else {
        // some non constexpr alg 
       return 1;
    }
}

Если перегрузку сложно внести в стандарт, неплохо-бы было иметь хотя-бы стандартный оператор проверки на константность аргумента. Скажем что-то вроде:

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