2016-06-21 20 views
1

Gibt es eine Möglichkeit, ein initializer_list zu verwenden, um ein bitset zu konstruieren?Verwenden einer initializer_list mit Bitset

Zum Beispiel würde ich gerne tun:

const auto msb = false; 
const auto b = true; 
const auto lsb = false; 
const bitset<3> foo = {msb, b, lsb}; 

Aber wenn ich das versuche ich:

error: could not convert {msb, b, lsb} from '<brace-enclosed initializer list>' to const std::bitset<3u>

Muss ich Verschiebungen verwenden, um eine unsigned long zu konstruieren foo zu initialisieren, oder Gibt es einen Weg, dies zu tun, von dem ich nichts weiß?

Antwort

3

Es gibt keinen Konstruktor, um ein Bitset direkt aus einer Initialisiererliste aufzubauen. Hier finden Sie eine Funktion benötigen:

#include <bitset> 
#include <initializer_list> 
#include <iostream> 

auto to_bitset(std::initializer_list<bool> il) 
{ 
    using ul = unsigned long; 
    auto bits = ul(0); 
    if (il.size()) 
    { 
     auto mask = ul(1) << (il.size() - 1); 

     for (auto b : il) { 
      if (b) { 
       bits |= mask; 
      } 
      mask >>= 1; 
     } 
    } 
    return std::bitset<3> { bits }; 

} 

int main() 
{ 
    auto bs = to_bitset({true, false, true}); 

    std::cout << bs << std::endl; 
} 

erwarteten Ergebnisse:

101 

Wie in den Kommentaren erwähnt, eine variadische Version ist ebenfalls möglich.

#include <bitset> 
#include <iostream> 
#include <utility> 

namespace detail { 
    template<std::size_t...Is, class Tuple> 
    auto to_bitset(std::index_sequence<Is...>, Tuple&& tuple) 
    { 
     static constexpr auto size = sizeof...(Is); 
     using expand = int[]; 
     unsigned long bits = 0; 
     void(expand { 
      0, 
      ((bits |= std::get<Is>(tuple) ? 1ul << (size - Is - 1) : 0),0)... 
     }); 
     return std::bitset<size>(bits); 
    } 
} 

template<class...Bools> 
auto to_bitset(Bools&&...bools) 
{ 
    return detail::to_bitset(std::make_index_sequence<sizeof...(Bools)>(), 
          std::make_tuple(bool(bools)...)); 
} 

int main() 
{ 
    auto bs = to_bitset(true, false, true); 

    std::cout << bs << std::endl; 
} 
+0

Die Antwort ist also ich die Verschiebungen zu tun haben, aber die Funktion ist eine nette Geste. –

+0

@ JonathanMee 'fraid so. TBH eine Template-Funktion in Bezug auf variadic bool könnte an dieser Stelle eleganter sein. –