Как да кажа на static_assert, че аргументите на функцията constexpr са const?

Имам функция constexpr, която изглежда нещо подобно:

constexpr int foo(int bar)
{
   static_assert(bar>arbitrary_number, "Use a lower number please");

   return something_const;
}

Въпреки това, компилирането на това с GCC 4.6.3 продължава да ми казва

грешка: 'лента' не може да се появи в постоянен израз

Пробвах нещо подобно

constexpr int foo(constexpr const int bar)
{
   static_assert(bar>arbitrary_number, "Use a lower number please");

   return something_const;
}

но constexpr не може да се използва за аргументи на функцията.

Има ли някакъв прост начин да кажете на компилатора, че лентата винаги е константа за време на компилиране?


person TravisG    schedule 20.03.2012    source източник
comment
Ами сега, напълно забравих да кодифицирам тази част. Благодаря @Henrik   -  person TravisG    schedule 20.03.2012
comment
Функция constexpr може да бъде извикана с неконстантни аргументи, тя просто губи своята constexpr'ness.   -  person Benjamin Lindley    schedule 20.03.2012
comment
възможен дубликат на C++11 - static_assert във функцията constexpr?   -  person Luc Touraille    schedule 11.06.2012


Отговори (3)


Има ли някакъв прост начин да кажете на компилатора, че лентата винаги е константа за време на компилиране?

Ако bar винаги е константа на времето за компилиране, тогава трябва да напишете функцията си като:

template<int bar>
constexpr int foo()
{
   static_assert(bar>arbitrary_number, "Use a lower number please");
   return something_const;
}

Защото, ако не го направите и вместо това напишете това, което вече сте написали, тогава в този случай функцията може да бъде извикана и с аргумент non-const ; просто когато подадете неконстантен аргумент, тогава функцията ще загуби своята constexpr-ност.

Имайте предвид, че в горния код arbitrary_number също трябва да бъде постоянен израз, в противен случай няма да се компилира.

person Nawaz    schedule 20.03.2012
comment
какъв тип синтаксис е template<int bar>? пълна специализация на шаблон като template <> ...? - person mbed_dev; 16.08.2018

constexpr функциите може да бъдат оценени по време на компилация, това не е принудено от стандарта като цяло (можете да накарате функцията да бъде оценена по време на компилация, като я използвате в постоянен израз като инициализиране на constexpr променлива с нея ).

Също така, аргументите на функция constexpr всъщност не са постоянни, те могат да се променят с всяко извикване (дори ако се оценяват по време на компилация).

Едно заобикаляне е да се използва нетипов шаблон за предаване на bar, ако винаги е константа за време на компилиране (което изглежда е).

person Xeo    schedule 20.03.2012

foo може да се използва по следния начин:

int i;
std::cin >> i;
foo("foo", i);

Както можете да видите, i не е точно постоянен израз по-горе, но все пак може да се използва с constexpr функции. constexpr функции (и шаблони за функции) са странен звяр, който гарантира, че напр. foo(p, i) е постоянен израз, ако p и i също са, но все още могат да се използват като обикновени функции.

Ако аргументите на вашите функции наистина са предназначени винаги да бъдат постоянни изрази, тогава те трябва да бъдат аргументи на шаблон, а не аргументи на функции.

person Luc Danton    schedule 20.03.2012