[英]Is it possible to check if const value is known at compile time?
目前我正在重写/扩展我的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 <...> :: Value:
template<typename... Ts> class Variant
{
public:
static const size_t MaxValueSize = ConstMax<size_t, sizeof(Ts)...>::Value;
};
这导致max = 90
。 我使用gdb逐步调试此代码,似乎在分配max期间没有执行函数调用。
我的问题:
ConstMax<...>::Value
在编译时始终是已知的吗? constexpr
函数/方法是否在编译时进行评估? 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
,它将破坏编译过程。
- 我可以安全地假设ConstMax <...> :: Value在编译时始终是已知的吗?
是的,因为它是用常量表达式初始化的。 但是我将Value
修改为constexpr
而不仅仅是const
。
- 有没有办法检查constexpr函数/方法是否在编译时进行评估?
是。 尝试在constexpr
表达式中使用它们。 如果它有效,它们将在编译时进行评估。 如果它无法编译,那么它在编译时不会被评估。
- 我理解定义为constexpr的成员/方法/函数不一定在编译期间进行评估,将Value定义为静态const的事实是否改变了这一点,或者我最好将这个特定情况作为递归模板类实现?
如果在常量表达式中使用成员,则强制在编译时对它们进行求值。 所以,如果你关心,我只需要确保用常量表达式来评估它们(通过constexpr
)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.