是否可以在编译时检查const值是否已知
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<…>更难验证的示例:在编译期间实际评估了值:
template<typename... Ts> class Variant
{
public:
static const size_t MaxValueSize = ConstMax<size_t, sizeof(Ts)...>::Value;
};
从而产生CCD_ 1。我使用gdb逐步完成了这段代码,在分配最大期间似乎没有执行任何函数调用
我的问题:
- 我可以放心地假设
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<…>:值在编译时总是已知的
是的,因为它是用常量表达式初始化的。但我会将max = 90
0修改为constexpr
,而不仅仅是const
。
- 有没有办法检查constexpr函数/方法是否在编译时求值
是。尝试在constexpr
表达式中使用它们。如果有效,则在编译时对它们进行评估。如果它未能编译,那么在编译时就不会对它进行评估。
- 我知道定义为constexpr的成员/方法/函数在编译时不一定要求值,Value被定义为静态const这一事实会改变这一点吗?还是我最好将此特定情况实现为递归模板类
如果在常量表达式中使用成员,则会强制在编译时对其求值。所以,如果你介意的话,我只需要确保用常量表达式(通过constexpr
)来评估它们。
相关文章:
- 是否应该在模板化代码中完全避免const
- 如果变量名称不跟在 char* 后面,const char* 是否有效?
- 是否有技术原因阻止 Java 中的 final C++ 像 const 一样严格?
- 知道模板参数在编译时是否为 const char*?
- "this"指向的对象是否与 const 对象相同?
- c++ 是否保证标头初始化的静态 const 成员跨编译单元和库共享单个实例?
- std::vector::assign/std::vector::operator=(const&) 是否保证在"this"中重用缓冲区?
- const-ref传递的模板化参数是否经过优化,以便在足够小时按值传递
- 是否允许使用初始值设定项列表将const数组引用实例化为构造函数参数
- const变量是否可以在具有默认值的参数中赋值(作为可选参数)
- 如何检查函数是否真的获得了定义为 const 的变量?
- 修改数据是否由 const shared_ptr&Ok 传递?
- 从内部使用静态 std::string 的函数返回 const char * 是否安全?
- 是否可以交换在 c++ 中作为函数 func(say) 中的参数传递的 const 向量的两个元素,例如:vector<int>func (const vector<int>&
- 编译器在 const ref 类型参数上使用临时对象时是否应该警告不安全的行为?
- 将shared_ptr转换为<T> shared_ptr<const T>是否会更改它所指向的对象?
- 是否可以按模板类型更改静态 const 类成员的值
- 是否可以翻新(TR)QSTRING CONST
- 如何避免重复的const和非const虚拟函数?是否可以
- 添加C++前缀是否"const"硬件级别执行任何不同操作,或者只是对编码人员的保护?