C++11 模板函数"implicity"将位集<N>转换为"unsigned long"

C++11 Template function to "implicity" convert bitset<N> to "unsigned long"

本文关键字:gt 转换 unsigned lt long 函数 implicity C++11      更新时间:2023-10-16

我可以创建一个 C++11 模板函数来显式地将位集转换为无符号长整型:

template<size_t N>
unsigned long U(bitset<N> x) {
return x.to_ulong();
}
// Explicit conversion
unsigned long y = U(bitset<4>("1010"));

有没有办法使用 C++11 模板帮助程序函数将位集"隐式"转换为无符号长整型。 例如,如果我将位集分配给无符号长整型,那么我希望它自动将位集转换为正确的类型:

// What Template Function in C++11?
// Implicit Conversion
unsigned long z = bitset<4>("1010");

(如果无法使用 C++11 模板函数创建隐式转换规则以转换为"无符号长整型",也可以从具有将函数转换为无符号长整型的位集派生一个新类。 这也有可能吗?

要将A转换为B,请执行以下任一操作:

  • B必须有一个非显式构造函数A,或者
  • A必须具有非显式转换operator B()

这两个函数只能是成员函数。

由于您无法修改std::bitsetunsigned long因此答案是:不可以,您不能隐式std::bitset转换为unsigned long。只是明确地

您可以将std::bitset包装在您自己的隐式可转换类中:

template<size_t N>
class MyBitset
{
public:
// constructors elided here
operator unsigned long()
{
return _bitset.to_ulong();
}
operator std::bitset<N>()
{
return _bitset; // Note that you get a copy here.
}
private:
std::bitset<N> _bitset;
};

演示

如果你试图从namespace std中的非多态类(即那些没有虚拟析构函数的类(派生,你不是在写惯用的C++,不要这样做。以上是否真的是解决您的问题的方法,我们无法判断。如果您只需要从位字符串中unsigned long常量,则可以跳过类包装器并直接将其构造函数替换为模板化函数:

template<size_t N, class CharT>
unsigned long toUlong(const CharT* str,
typename std::basic_string<CharT>::size_type n =
std::basic_string<CharT>::npos,
CharT zero = CharT('0'),
CharT one = CharT('1'))
{
return std::bitset<N>(str, n, zero, one).to_ulong();
}

演示

另一种基于Maxim的Bullet 2的解决方案:

template<size_t N>
class bits : public bitset<N> {
public:
bits(unsigned long num) : bitset<N>(num) {}
bits(char* binstr) : bitset<N>(binstr){}
operator unsigned long() {
return this->to_ulong();
}
// Slice Bit Range
unsigned long slice(unsigned L, unsigned R)
{
unsigned long P1;
unsigned long P2;
if (L>R) {
P2 = L;
P1 = R;
}
else {
P2 = R;
P1 = L;
}
unsigned long x = this->to_ulong();
unsigned long W = P2 - P1 + 1;
unsigned long Value = (x >> P1) & ((1<<W) - 1);
return Value;
}
// Return Hex String
string hstr() {
stringstream xx;
xx << "0x" << hex << this->to_ulong();
return xx.str();
}
};
int main(int argc, char** argv) {
// Implicit conversion...
unsigned long xxx = bits<4>("0101");
unsigned long yyy = bits<4>(xxx).slice(1, 2);
}