Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass bitset of any size to a function?

Tags:

c++

templates

The following program compiles fine.

#include <iostream>
#include <bitset>

void foo(std::bitset<10> n)
{
    std::cout << n.size() << "\n";
}

int main()
{
    std::bitset<10> n;
    foo(n);
}
$ g++ -std=c++11 -Wall -Wextra -pedantic foo.cpp
$ ./a.out 
10

How can I modify the foo() function such that it can accept bitset of any size?

like image 875
Lone Learner Avatar asked Dec 24 '22 19:12

Lone Learner


2 Answers

That's what templates supposed to do. So make foo a function template with non-type template parameter:

template<std::size_t N>
void foo(std::bitset<N> n)
{
    std::cout << n.size() << "\n";
}

then

std::bitset<10> n10;
foo(n10);
std::bitset<20> n20;
foo(n20);
like image 167
songyuanyao Avatar answered Jan 08 '23 15:01

songyuanyao


The std::bitset<N> are types, so you can create a template function that accept a generic type

template <typename T>
void foo (T n)
 { std::cout << n.size() << "\n"; }

Observe that this function will work with not only with all std::bitset but also with all types with a size() member that return a value that can be send to std::cout, as a lot of STL containers (std::set, std::vector, std::map, etc).

So, by example, you can also call foo() as follows

 std::vector<int> v(20);
 foo(v);

This can be good or bad, according to your requirements.

If you want a function that accept only a std::bitset, so you can follows the solution suggested by songyuanyao: you can explicit std::bitset and templatize the dimension.

template <std::size_t N>
void foo (std::bitset<N> n)
{ std::cout << n.size() << "\n"; }

but, in this case, there is no need to use size(); you can use directly N

template <std::size_t N>
void foo (std::bitset<N>)
{ std::cout << N << "\n"; }

If, in addiction, you want that foo accept a std::bitset<N> with (by example) N in a range of values (say [10,20[), and you can use C++11, you can use SFINAE and write something as follows

template <std::size_t N>
typename std::enable_if<(N >= 10U) && (N < 20U)>::type foo (std::bitset<N>)
 { std::cout << N << "\n"; }

Now you have

std::bitset<10> n10;
std::bitset<15> n15;
std::bitset<25> n25;

foo(n10);    // compile
foo(n15);    // compile
// foo(n25); // compilation error
like image 28
max66 Avatar answered Jan 08 '23 15:01

max66