如何告诉static_assert constexpr函数参数是const

How to tell static_assert that constexpr function arguments are const?

本文关键字:函数 参数 const constexpr assert 何告诉 static      更新时间:2023-10-16

我有一个constexpr函数,看起来像这样:

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

然而,用GCC 4.6.3编译它一直告诉我

错误:"bar"不能出现在常量表达式中

我试过类似的东西

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

但是constexpr不能用于函数参数。

有没有一些简单的方法可以告诉编译器bar总是一个编译时常数?

有没有一些简单的方法可以告诉编译器bar总是一个编译时常数?

如果bar总是编译时间常数,那么您应该将函数写成:

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

因为如果你不这样做,而是写你已经写过的东西,那么在这种情况下,函数也可以用非常量参数来调用;只是当您传递非常量参数时,函数将丢失它的constexpr-ness。

注意,在上面的代码中,arbitrary_number也应该是常量表达式,否则它将不会编译。

constexpr函数可以在编译时进行求值,这通常不是标准强制的(您可以通过在常量表达式中使用它来强制在编译时对函数进行求值,就像用它初始化constexpr变量一样)。

此外,constexpr函数的自变量实际上并不是恒定的,它们可能会随着每次调用而变化(即使在编译时求值)。

一种解决方法是使用非类型模板来传递bar,如果它总是一个编译时常数(看起来是)。

foo可按以下方式使用:

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

正如您所看到的,i并不是上面的常量表达式,但它仍然可以与constexpr函数一起使用。constexpr函数(和函数模板)是一个奇怪的野兽,它保证了例如foo(p, i)是一个常量表达式,当pi也是时,仍然可以像正则函数一样使用。

如果函数的参数确实是常量表达式,那么它们应该是模板参数,而不是函数参数。