如何检查模板参数是否是 2 的幂
How do I check if a template parameter is a power of two?
我想创建一个静态分配 2^N 字节数组的结构,但我不希望此结构的用户将此大小指定为指数。例:
my_stupid_array<char, 32> a1; // I want this!
my_stupid_array<char, 5> a2; // And not this...
如何检查此模板参数是否是 2 的幂,并用一条很好的消息警告用户?
我已经能够使用一个简单的模板来检查这一点:
template<int N>
struct is_power_of_two {
enum {val = (N >= 1) & !(N & (N - 1))};
};
但是,我无法通过理智的消息警告用户。有什么想法吗?
编辑
修复了模棱两可的示例。
编辑
1 确实是 2 的幂。修复了!:)
编辑
使用 BOOST_STATIC_ASSERT,我在 GCC 中收到此代码的编译错误:
template<int N>
struct is_power_of_two {
enum {val = (N >= 1) & !(N & (N - 1))};
BOOST_STATIC_ASSERT(val);
};
错误
..main.cpp:29:1: error: invalid application of 'sizeof' to incomplete type 'boost::STATIC_ASSERTION_FAILURE<false>'
http://ideone.com/cMfEf
编辑
哦,我明白了。这就是断言失败时我应该得到的消息。但这无法给用户一些理智的信息。:(
这些天,有了constexpr
和一些小技巧,你可以
constexpr bool is_powerof2(int v) {
return v && ((v & (v - 1)) == 0);
}
static_assert救援(仅限C++11,取消注释BOOST_STATIC_ASSERT C++03(:
#include<iostream>
// #include <boost/static_assert.hpp>
template<int N>
struct is_power_of_two {
enum {val = N && !(N & (N - 1))};
static_assert(val, "should use a power of 2 as template parameter");
// BOOST_STATIC_ASSERT(val); // without C++11 support, won't take a string message
};
int main()
{
std::cout << is_power_of_two<2>::val << "n";
std::cout << is_power_of_two<3>::val << "n";
}
用于 C++11 的 Ideone 输出
用于 C++03 的 Ideone 输出
UPDATE1:其他想法(我知道你不想要这个,但对于大指数来说要容易得多(:
template<int N>
make_power_of_two
{
enum { val = 1 << N };
};
my_stupid_array<char, make_power_of_two<5>::val > a1; // size 2^5 = 32
UPDATE2:根据聊天中@sehe的评论,您也可以为constexpr
功能执行此操作
constexpr bool is_power_of_two(int x)
{
return x && ((x & (x-1)) == 0);
}
您可以使用
static_assert
提供错误消息:
template<int N>
struct is_power_of_two {
static_assert((N > 1) & !(N & (N - 1)), "Template parameter must be a power of two.");
};
相关文章:
- C++14 及更高版本是否允许 Lambda 函数的默认参数?如果是这样,怎么办?
- 继承是否是将一组模型参数传递给不同类的可行解决方案
- 移动 l 值参考参数是否是一种不好的做法?
- 限制C++中允许的模板参数是否被认为是不良样式?
- 模板参数是否可以是引用类型?
- 检查传递给成员函数的参数是否是对象本身
- 如何检查模板参数是否是具有给定签名的可调用对象
- 模板参数是否可以无缝匹配类型和模板,也许是可变变量的一部分
- 使用 const CString& 而不是单独使用 CString 作为函数参数是否有任何性能优势?
- 在编译时检查模板参数是否是一种字符串
- 在声明中省略参数名称是否是一种好的做法
- 如何识别模板参数参数是否是模板内结构中另一个类的实例?C++
- 是否可以知道该参数是否是默认的
- std::函数的复制构造函数是否要求模板类型的参数类型是完整的类型
- 使用可变参数模板创建传递新对象的更安全方式是否是个好主意
- 如何检查模板参数是否是 2 的幂
- 有没有办法检测基元参数是否是可变大小的
- 检查模板参数是否为"true"可调用对象的正确方法是什么?
- 此错误消息是否正确:非类型模板参数不是常量表达式
- C++ 多态函数以 void * 和其他指针类型为参数:是否被认为是模棱两可的