6

テンプレートを使用して、整数型をバイナリ値の文字列表現に変換しています。私は以下を使用しました:

template<typename T>
std::string ToBinary(const T& value)
{
    const std::bitset<std::numeric_limits<T>::digits + 1> bs(value);
    const std::string s(bs.to_string());

    return s;
}

int では機能しますが、 unsigned int ではコンパイルされません:

unsigned int buffer_u[10];
int buffer_i[10];
...
ToBinary(buffer_i[1]); //compile and works
ToBinary(buffer_u[1]); //doesn't compile -- ambiguous overload

理由を説明していただけますか?

編集:

はい、VS2010 を使用しています

4

3 に答える 3

4

あなたの ToBinary 呼び出しがあいまいではなく、符号なしの値を持つビットセットのコンストラクター呼び出しです。残念ながら、これは VC++ のバグです: http://connect.microsoft.com/VisualStudio/feedback/details/532897/problems-constructing-a-bitset-from-an-unsigned-long-in-the-vc-rc

編集 - 回避策:

template<>
std::string ToBinary<unsigned int>(const unsigned int& value)
{
    const std::bitset<std::numeric_limits<unsigned int>::digits> bs(static_cast<unsigned long long>(value));
    return bs.to_string();
}
于 2012-01-25T11:05:12.200 に答える
0

VC10をお使いですか?既に問題が報告されています: Microsoft connect. また、次のように、32 ビットの場合は型を int にキャストすることで修正できると思います。

string s = ToBinary(*reinterpret_cast<int*>(&buffer_u[1]));

これは、必要に応じてメソッド内でも実行できます。ただし、再解釈の結果を算術演算に使用するべきではありません。;)

私にとっては回避策としてうまく機能します(しかし、かなり醜いように見えます)

template<typename T>
std::string ToBinary(const T& value)
{
    switch (sizeof(T))
    {
    case 8:
        return std::bitset<std::numeric_limits<T>::digits + 1>(*reinterpret_cast<const long*>(&value)).to_string();
    case 4:
        return std::bitset<std::numeric_limits<T>::digits + 1>(*reinterpret_cast<const int*>(&value)).to_string();
    case 2:
        return std::bitset<std::numeric_limits<T>::digits + 1>(*reinterpret_cast<const short*>(&value)).to_string();
    case 1:
        return std::bitset<std::numeric_limits<T>::digits + 1>(*reinterpret_cast<const char*>(&value)).to_string();
    }
    return "n/a";
}
于 2012-01-25T11:08:56.067 に答える
0

標準 (FDIS n3290) を見ると、std::bitset複数のコンストラクターがあることがわかります。

まずこれがあります:

20.5.1 ビットセットコンストラクタ [bitset.cons]

constexpr bitset(unsigned long long val) noexcept;

効果: クラス bitset のオブジェクトを構築し、最初の M ビット位置を val の対応するビット値に初期化します。M は、N と unsigned long long の値表現 (3.9) のビット数の小さい方です。M < N の場合、残りのビット位置はゼロに初期化されます。

次に、これもあり、これを呼び出すと、物事が曖昧になる可能性があると思われますunsigned int

template <class charT>
explicit bitset(
const charT* str,
typename basic_string<charT>::size_type n = basic_string<charT>::npos,
charT zero = charT(’0’), charT one = charT(’1’));

効果: クラス bitset のオブジェクトを構築します。

bitset( n == basic_string<charT>::npos ? basic_string<charT>(str) :
basic_string<charT>(str, n), 0, n, zero, one)
于 2012-01-25T11:09:05.187 に答える