C++ 强制编译时constexpr
在C++11中,我们得到C++ 强制编译时constexpr,c++,c++11,constexpr,C++,C++11,Constexpr,在C++11中,我们得到constexpr: constexpr int foo (int x) { return x + 1; } 使用动态值x调用foo时是否可能出现编译时错误?也就是说,我想创建一个foo,这样只能传入constepr参数。用元函数替换它: template <int x> struct foo { static constexpr int value = x + 1; }; template struct foo{static constexpr
constexpr
:
constexpr int foo (int x) {
return x + 1;
}
使用动态值
x
调用foo
时是否可能出现编译时错误?也就是说,我想创建一个foo
,这样只能传入constepr
参数。用元函数替换它:
template <int x> struct foo { static constexpr int value = x + 1; };
template struct foo{static constexpr int value=x+1;};
用法:
foo<12>::value
foo::value
我将使用静态断言
,如本例所示
#include<iostream>
constexpr int foo(int x) {
return x+1;
}
int main() {
// Works since its static
std::cout << foo(2) << std::endl;
static_assert(foo(2) || foo(2) == 0, "Not Static");
// Throws an compile error
int in = 3;
std::cout << foo(in) << std::endl;
static_assert(foo(in) || foo(in) == 0, "Not Static");
}
#包括
constexpr int foo(int x){
返回x+1;
}
int main(){
//因为它是静态的
std::cout不幸的是,除非绝对必要,否则无法保证编译器会对constepr
函数进行求值,即使是最微不足道的函数。也就是说,除非它出现在编译时需要其值的位置,例如在模板中。为了强制编译器在c在Compilation中,您可以执行以下操作:
constexpr int foo_implementation (int x) {
return x + 1;
}
#define foo(x) std::integral_constant<int, foo_implementation(x)>::value
这种方法的好处在于它保证了编译时的计算,如果将运行时变量传递给foo
,则会出现编译错误:
int a = 2;
int f = foo(a); /* Error: invalid template argument for 'std::integral_constant',
expected compile-time constant expression */
不太好的地方在于它需要一个宏,但如果您既想要有保证的编译时计算,又想要漂亮的代码,这似乎是目前不可避免的。(不过我希望被证明是错误的!)您可以始终将其转换为函数模板:template int foo(){return x+1;}
注意,constexpr
被部分调用,以抵消您将在这里的答案中看到的所有语法解决方法。#define foo(N)foo()
在我看来是可行的。或者,在未计算的上下文中,#define REQUIRE_CEXPR(E)[{constexpr auto x=E;return x;}()
您可以说foo(REQUIRE_CEXPR(1+2))
(C++14)。对于C++11,您可以执行[]()->typename std::decation::type
来显式指定类型。更难看的是:)非答案:将结果存储在constexpr
中。或者更好的是,给它一个操作符()
这类似于函数调用。@rubenvb:更好的是,使用变量模板:template int bar=foo::value;
。用法:bar
。在C++14中提供。我没有带constexpr
的编译器ATM,但这个想法不会扩展到将静态断言直接放入foo
?例如。constexpr int foo(int x){static_assert(x==x,“Not static”);返回x+1;}
@ThomasEding。您可以这样做,但这样会失去使用与运行时求值函数相同的函数的灵活性。由于在编译时选中了static_assert
,因此也不会影响运行时。
int a = 2;
int f = foo(a); /* Error: invalid template argument for 'std::integral_constant',
expected compile-time constant expression */