Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/124.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++ 常量的编译时检查_C++_Templates_Template Meta Programming_Compile Time_Compile Time Constant - Fatal编程技术网

C++ 常量的编译时检查

C++ 常量的编译时检查,c++,templates,template-meta-programming,compile-time,compile-time-constant,C++,Templates,Template Meta Programming,Compile Time,Compile Time Constant,如果我有一个函数 int calcStuff_dynamic(const int a, const int b) 还有一些模板元代码 template<int a, int b> struct calcStuff_static { static const int value = //some more code }; 模板 结构calcStuff_静态{ static const int value=//还有一些代码 }; 有没有办法写一个包装器 int calcSt

如果我有一个函数

int calcStuff_dynamic(const int a, const int b)
还有一些模板元代码

template<int a, int b>
struct calcStuff_static {
    static const int value = //some more code
};
模板
结构calcStuff_静态{
static const int value=//还有一些代码
};
有没有办法写一个包装器

int calcStuff(const int a, const int b) {
    IF_THESE_ARE_KNOWN_CONSTANTS_AT_COMPILE_TIME(a, b)
        return calcStuff_static<a, b>::value;
    ELSE_TEMPLATE_WOULD_FAIL
        return calcStuff_dynamic(a, b);
}
intcalcstuff(常数inta,常数intb){
如果这些是编译时已知的常数(a,b)
返回calcStuff_static::value;
否则模板就会失败
返回calcStuff_动态(a,b);
}

您不能这样做,但它将由智能编译器完成

可能想到的第一个解决方案是将SFINAE与constexpr值结合使用。在这种情况下,我们需要一些东西来检测constexpr值

但是,在编译时没有类似于检测已知值的东西。另一方面,函数
is_const
没有用处,因为
constepr
不是类型的一部分。所以,你不能这样做(或者至少我不知道一个简单的解决方案)

但是,如果您知道有一个优化问题,即有许多编译器在编译时为已知值计算函数的最终值,您会很高兴。例如,在GCC中,有“SCEV最终值替换”


因此,当参数未知时,您应该只使用该动态函数,编译器将根据您的意愿(如果可能)执行该操作。

GCC、Clang和英特尔编译器都支持检查该值是否为编译时常量,并在这种情况下提供优化表达式


对于所有其他编译器,可以使用动态计算作为回退。(我不知道Visual Studio有一个等价物。)

你说的“如果这些已知”是什么意思?你在静态情况下使用的算法与在非静态情况下使用的算法不同吗?为什么?否则,您要查找的是
constepr
。请参阅
calcStuff
中的
a
b
不是常量表达式,因此它们不能用作
calcStuff\u dynamic
中的模板参数。GCC4.3太旧了,当您赋予它无意义的编译标志时甚至不会呕吐:-)哦,太酷了。SCEV是否对元编程进行了一些模拟使用?当我查看avr-g++-4.3上的
gcd(3432,gcd(2312312))
程序集时,我发现它没有展开。这是g++的新特性吗?谢谢。在这种情况下,它实际上不起作用:
intcalcstuff(constinta,constinb){return\uuuu-builtin\u-constant\u-p(a)&&&&&uu-builtin\u-constant\u-p(b)}calcStuff\u-static::value:calcStuff\u-dynamic(a,b)}
@user315118如果您表达
a&&b,它能起作用吗?expr1:expr2
as
a?(b?expr1:expr2):expr2