C ++ 11用于“隐式”的模板函数将bitset <n>转换为“ unsigned long”

时间:2018-06-20 15:49:31

标签: c++ c++11 bitset

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

FileOutputStream out = null;
try {
    out = new FileOutputStream(filename);
    mBitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
    // PNG is a lossless format, the compression factor (100) is ignored
} catch (Exception e) {
    e.printStackTrace();
} finally {
    try {
        if (out != null) {
            out.close();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

有没有一种方法可以使用C ++ 11模板辅助函数将位集“隐式”转换为无符号长整数。例如,如果我将一个位集分配给一个无符号的long,那么我希望它自动将位集转换为正确的类型:

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模板函数创建隐式转换规则以将其转换为“ unsigned long”,那么也可以从具有强制转换为unsigned long的位集派生新类。以及?)

3 个答案:

答案 0 :(得分:7)

隐式A转换为B,要么:

  • B必须具有采用A的非显式构造函数,或者
  • A必须进行非明确转换operator B()

这两个都必须仅是成员函数。

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

答案 1 :(得分:2)

您可以将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;
};

Demo

如果您试图从namespace std中的非多态类(即那些没有虚拟析构函数的类)派生,那么您就是not writing idiomatic 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();
}

Demo

答案 2 :(得分:0)

另一种基于Maxim项目符号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);
}