Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/163.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 强制编译时constexpr_C++_C++11_Constexpr - Fatal编程技术网

C++ 强制编译时constexpr

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

在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 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 */