1

I need to build 2D array of bitset, and I want to get the size of the array and size of bitset from user. Since its template and the value must be const how can I do that?

int main(int argc, char* argv[]) {
int const LEN ;
int const NUMBER;
if ( argc == 3 ) 
{
    LEN =  atoi(argv[1]);
    NUMBER =  atoi(argv[2]);
}
else{
    LEN = 1000;
    NUMBER = 800;
}
bitset<LEN> b[NUMBER];
}

3 Answers 3

4

You can't. You need to know the size in compile time to use bitset. You can use vector<bool> as replacement though, which is really a bit vector, not a vector of actual bools.

Sign up to request clarification or add additional context in comments.

3 Comments

For my own reference, I know its usually a bitset, but is it guaranteed to be a bitset?
I have to use bitset , I don't want to use vector
@Am1rr3zA Well my only advice then is to use a really big bitset which is definitely bigger than you will need. But you don't need to use bitset. vector<bool> is basically the same.
3

If you can set a limit to how big a bitset size you can use, you can cheat.

// invokes target<i>{}() if i >= min and i < max
template<template<size_t>class target, size_t max, size_t min=0>
struct magic_switch {
  void operator()( size_t i ) const {
    constexpr size_t mid = (min+max-1)/2;
    if (i==max-1) target<max-1>{}();
    else if(i<mid) magic_switch<target, mid,min>{}(i);
    else magic_switch<target, max-1,mid>{}(i);
  }
};
template<template<size_t>class target, size_t min>
struct magic_switch<target, min, min> {
  void operator()( size_t i ) const {} // do nothing
};
int number;
template<size_t len>
struct program {
  template<size_t number>
  struct p2 {
    void operator()() const {
      std::bitset<len> arr[number];
      // code
    }
  };
  void operator()() const {
    magic_switch<p2, 1001, 1>{}(number);
  }
};

int main(int argc, char const* argv[]) {
  int len;
  if ( argc == 3 ) 
  {
    len =  atoi(argv[1]);
    number =  atoi(argv[2]);
  }
  magic_switch<program, 1001, 1>{}( len );
}

of course, this approach is completely nuts and a bad idea.

Basically I created 10000000 programs, one for each len x number, then did a massive chained if to figure out which one to run.

This can be made more performant by storing pointers to the programs in an array, then doing an array lookup instead of a 20-deep recursion. It is still a bad idea.

Do not use this solution. If you don't understand why you shouldn't use it, then trust me. If you do understand why you shouldn't use it, then this paragraph is redundant.

A faster magic_switch (some compilers won't like it, and uses C++14 features):

template<template<size_t>class target, size_t max, size_t min=0>
struct magic_switch {
  template<size_t...Is>
  void operator()( std::index_sequence<Is...>, size_t i ) {
    using task = void(*)();
    static const task arr[] = {
      []{ target<min+Is>{}(); }...
    };
    arr[i-min]();
  }
  void operator()( size_t i ) const {
    (*this)( std::make_index_sequence<max-min>{}, i );
  }
};

here we build a jump table (in a static const array), do a lookup, and execute it.

Extending this to take/return args is relatively easy:

template<class Sig, template<size_t>class target, size_t max, size_t min=0>
struct magic_switch;
template<class R, class...Args, template<size_t>class target, size_t max, size_t min>
struct magic_switch<R(Args...), target, max, min> {
  template<size_t...Is>
  R operator()( std::index_sequence<Is...>, size_t i, Args&&...args ) {
    using task = R(*)(Args&&...);
    static const task arr[] = {
      [](Args&&...args)->R{
        return target<min+Is>{}(std::forward<Args>(args)...);
      }...
    };
    return arr[i-min](std::forward<Args>(args)...);
  }
  R operator()( size_t i, Args...args ) const {
    return (*this)(
      std::make_index_sequence<max-min>{},
      i,
      std::forward<Args>(args)...
    );
  }
};

Using this one will take away the requirement that the number variable be stored globally. As global variables are bad practice, this improves the code.

6 Comments

Thanks for your answer, I am forced to use bitset because of its performance but it seems it's better to switch to Vector and solve my problem. anyway thanks.
@am1rr I think you are making incorrect assumptions about relative performance
There is no kill like overkill
@dave What, I could have done quadratic code generation instead of linear. And log depth template recursion to "allow" limits in the millions or billions. Can you say terabyte binaries? Why not add another zero or 3 then.
@dave ok, now it is overkill. 1 million programs generated, with fixed size arrays in each. And a standard-recommended compiler can handle upper limits of 1 million+ instead of 1000, which corresponds to trillions of programs generated. Happy now?
|
0

The simple answer is -- you can't do this. The std::bitset uses compile time values.

You can use vector<bool>, or the boost library's dynamic_bitset:

http://www.boost.org/doc/libs/1_57_0/libs/dynamic_bitset/dynamic_bitset.html

2 Comments

I have to use bitset , there isn't any trick so I can get the size from user?
No, there is no trick. And why the "I have to use..."? What is stopping you from using the vector<bool> or the boost library?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.