【发布时间】:2018-01-04 06:03:31
【问题描述】:
我对元编程的语言特性有点陌生,我正在尝试用public static const variables 制作一个简单的class,它将通过编译时间常量设置其值:
我想要实现的目标:我想计算一些指数的幂,这些指数以转换为基数为2 的位数为单位的字节数来衡量。所有计算均以 2 为基数。
例子:
1 byte(s) = 8 bits: value = pow(2, 8) = 256; 2 byte(s) = 16 bits: value = pow(2, 16) = 65536 4 byte(s) = 32 bits: value = pow(2, 32) = 4294967296 8 byte(s) = 64 bits: value = pow(2, 64) = 18446744073709551616
我尝试编写一个函数来计算在尝试使用constexpr 或const 时所需的值,并且我尝试使用templates。我想像这样使用const function、constexpr function 或function template:
// constexpr function
constexpr std::uint64_t pow2( const std::uint32_t expInBytes, const std::uint32_t base = 2 ) {
const std::uint32_t expInBits = expInBytes * CHAR_BIT;
return static_cast<std::uint64_t>( expInBits == 0 ? 1 : base * pow2( base, expInBits - 1 ) );
}
// or function template
template<std::uint32_t expInbytes>
constexpr std::uint64_t pow2() {
const std::uint32_t base = 2;
const std::uint32_t expInBits = expInBytes * CHAR_BIT;
return (expInBits == 0 ? 1 : base * pow2<expInBytes-1>() );
}
template<>
constexpr std::uint64_t pow2<0>() {
return 0;
};
// template parameter T not used but needed to use the class as such:
// BitCombinations<>::static_member;
template<typename T = const std::uint32_t>
class BitCombinations {
public: // template // non template
static const std::uint64_t ONE_BYTE = pow2<1>(); // pow2( 1 );
static const std::uint64_t TWO_BYTES = pow2<2>(); // pow2( 2 );
static const std::uint64_t FOUR_BYTES = pow2<4>(); // pow2( 4 );
static const std::uint64_t EIGHT_BYTES = pow2<8>(); // pow2( 8 );
};
通过我的努力,我产生了各种编译时、运行时错误等。最新尝试我能够获得上面pow2<>() 的模板版本来编译和运行,但是我没有得到正确的结果。
我不确定我对pow2 的实现是否错误,或者我的语法是否错误,或者我是否没有正确使用const 或constexpr,在某些情况下我一直得到integral constant overflow作为 MS Visual Studio 2017 CE 编译器的编译时错误。
我一直在为 pow2() 函数遵循这些模式:
- nullptr.me:C++11 constexpr : computing exp at compile time
- prosepoetrycode.potterpcs.net : A simple constexpr power function (C++)
- cppreference.com : math::exp2
- reformatcode.com : c++ power of integer, template meta programming
我似乎无法解决这个问题,也不知道还能尝试什么。
【问题讨论】:
标签: c++ templates c++14 c++17 constexpr