是否可以在编译时检查const值是否已知

Is it possible to check if const value is known at compile time?

本文关键字:是否 const 检查 编译      更新时间:2023-10-16

当前我正在重写/扩展我的C++实用程序库,同时考虑到新的C++11特性。其中一个新添加的是一个模板类,它给出了一组数字的最大值,希望在编译时。

template<typename T, T... Xs> class ConstMax
{
private:
template<typename... Ts> static constexpr T Max(Ts... xs);
template<typename Tx> static constexpr T Max(Tx x)
{
return x;
}
template<typename T1, typename T2, typename... Ts> static constexpr T Max(T1 x, T2 y, Ts... xs)
{
return y > x ? Max<T2, Ts...>(y, xs...) : Max<T1, Ts...>(x, xs...);
}
public:
static const T Value = Max(Xs...);
};

此类的一个示例用法:

int max = ConstMax<int, 1, 8, 66, 32, 90, 12, 33>::Value;

以下是另一个可能会使ConstMax<…>更难验证的示例:在编译期间实际评估了值:

template<typename... Ts> class Variant
{
public:
static const size_t MaxValueSize = ConstMax<size_t, sizeof(Ts)...>::Value;
};

从而产生CCD_ 1。我使用gdb逐步完成了这段代码,在分配最大期间似乎没有执行任何函数调用

我的问题:

  1. 我可以放心地假设ConstMax<...>::Value在编译时总是已知的吗
  2. 有没有办法检查constexpr函数/方法是否在编译时进行了评估
  3. 我知道定义为constexpr的成员/方法/函数在编译时不一定要求值,Value被定义为static const这一事实是否会改变这一点,或者我是否更适合将这种特定情况实现为递归模板类

要检查表达式是否为constexpr(即常量表达式),可以使用std::integral_constant类型的特性,如下所示:

#include <iostream>
#include <type_traits>
template<typename T, T... Xs> class ConstMax {
template<typename... Ts> static constexpr T Max(Ts... xs);
template<typename Tx> static constexpr T Max(Tx x) { return x;}
template<typename T1, typename T2, typename... Ts>
static constexpr T
Max(T1 x, T2 y, Ts... xs) {
return y > x ? Max<T2, Ts...>(y, xs...) : Max<T1, Ts...>(x, xs...);
}
public:
static const T Value = Max(Xs...);
};
int main() {
std::cout << std::integral_constant<int, ConstMax<int, 1, 8, 66, 32, 90, 12, 33>::Value>::value << std::endl;   
}

实时演示

如果不是constexpr,它将中断编译过程。

  1. 我可以安全地假设ConstMax<…>:值在编译时总是已知的

是的,因为它是用常量表达式初始化的。但我会将max = 900修改为constexpr,而不仅仅是const

  1. 有没有办法检查constexpr函数/方法是否在编译时求值

是。尝试在constexpr表达式中使用它们。如果有效,则在编译时对它们进行评估。如果它未能编译,那么在编译时就不会对它进行评估。

  1. 我知道定义为constexpr的成员/方法/函数在编译时不一定要求值,Value被定义为静态const这一事实会改变这一点吗?还是我最好将此特定情况实现为递归模板类

如果在常量表达式中使用成员,则会强制在编译时对其求值。所以,如果你介意的话,我只需要确保用常量表达式(通过constexpr)来评估它们。

相关文章: