Can we create the following array or something similar using template in c++ at compile time.
int powerOf2[] = {1,2,4,8,16,32,64,128,256}
This is the closest I got.
template <int Y> struct PowerArray{enum { value=2* PowerArray<Y-1>::value };};
but then to use I need something like PowerArray <i> which compiler gives error as i is dynamic variable.
You can use BOOST_PP_ENUM for this:
#include <iostream>
#include <cmath>
#include <boost/preprocessor/repetition/enum.hpp>
#define ORDER(z, n, text) std::pow(z,n)
int main() {
int const a[] = { BOOST_PP_ENUM(10, ORDER, ~) };
std::size_t const n = sizeof(a)/sizeof(int);
for(std::size_t i = 0 ; i != n ; ++i )
std::cout << a[i] << "\n";
return 0;
}
Output ideone:
1
2
4
8
16
32
64
128
256
512
This example is a modified version (to suit your need) of this:
Trick : filling array values using macros (code generation)
Nothing against using BOOST_PP_ENUM but I think your going for more of the kind of code I will show you.
What I would do, is I would make a constructor of your type class which just sets the array to the stuff you need. That way it does it as soon as the program builds and it stays nice and neat. AKA the proper way.
class Power
{
public:
Power();
void Output();
// Insert other functions here
private:
int powArray[10];
};
Then the implementation would be with a basic "for loop" to load them into the array you just created.
Power::Power()
{
for(int i=0;i<10;i++){
powArray[i] = pow(2,i);
}
}
void Power::Output()
{
for(int i=0;i<10;i++){
cout<<powArray[i]<<endl;
}
}
Hopes this helps...
Related
I am making a program where I have 2 vectors (clientvec and productslist) and I need to create a 2D boolean matrix where the columns is the size of productslist vector and the lines is the size of clientvec vector, but it gives me this error:
"expression must have a constant value"
Here is the code I used:
unsigned int lines = clientvec.size();
unsigned int columns = productslist.size();
bool matrixPublicity[lines][columns] = {false};
Pls help me..
Edit: I am new at c++ so assume I know nothing xD
Edit2: I already know for the answers that I cannot initialize an array with non constant values, now the question is how can I put them after initialize...
The error message is clear: :expression must have a constant value"
It means the array dimension cannot be of variable type. Only enums or pre-processor defined constants are valid.
See for more info:
Why can't I initialize a variable-sized array?
Edit: Since you mentioned you are new to C++, here is a piece of code that might help you:
#include <iostream>
#include <vector>
#include <bitset>
int main()
{
unsigned int lines = 10;
const unsigned int columns = 5;
std::vector<std::bitset<columns>> matrixPublicity;
matrixPublicity.resize(lines);
for(int i=0; i < lines; i++)
{
for(int j=0; j < columns; j++)
std::cout << matrixPublicity[i][j] <<' ';
std::cout<<'\n';
}
}
note that in this case, columns must be constant.
Edit 2: And if the size of lines are not the same, then you must stick to vector types:
typedef std::vector<bool> matrixLine;
std::vector<matrixLine> matrixPublicity;
now you can use resize method for the i-th line of the matrix, e.g.
matrixPublicity[1].resize(number_of_columns_in_line_2);
What you are trying to do would be the same as this:
std::vector<unsigned int> v1 { 1, 2, 3, 4, 5 };
std::vector<unsigned int> v2 { 6, 7, 8, 9 };
bool mat[v1.size()][v2.size()] = false;
This is how the compiler will interpret it without the temporaries and this is invalid. When you declare an array of any type its size has to be known at compile time.
bool mat[2][3] = false; // still invalid
bool mat[2][3] = { false }; // Okay
const int x = 5;
const int y = 7;
bool mat[x][y] = false; // invalid
bool mat[x][y] = { false }; // okay
// Even this is invalid
std::vector<int> v1{ 1, 2, 3 };
std::vector<int> v2{ 4, 5, 6, 7 };
const std::size_t x1 = v1.size();
const std::size_t y1 = v2.size();
bool mat2[x1][y1] = { false }; // Still won't compile.
Value to declare an array must be a constant expression.
Instead of making an array as you have tried to do, you could make a class template that will construct a matrix like object for you. Here is what I have come up with, now the overall design or pattern of this template will fit your condition but the actual implementation to generate the internal matrix will depend on your data and what you intend.
#include <vector>
#include <iostream>
#include <conio.h>
template <class T, class U>
class Matrix {
private:
std::vector<T> m_lines;
std::vector<T> m_cols;
std::vector<U> m_mat;
std::size_t m_size;
std::size_t m_lineCount;
std::size_t m_colsCount;
public:
Matrix() {};
Matrix( const std::vector<T>& lines, const std::vector<T>& cols ) :
m_lines(lines),
m_cols(cols),
m_lineCount( lines.size() ),
m_colsCount( cols.size() )
{
addVectors( lines, cols );
}
void addVectors( const std::vector<T>& v1, const std::vector<T>& v2 ) {
m_lines = v1;
m_cols = v2;
m_lineCount = m_lines.size();
m_colsCount = m_cols.size();
for ( unsigned int i = 0; i < m_lineCount; ++i ) {
for ( unsigned int j = 0; j < m_colsCount); j++ ) {
// This will depend on your implementation and how you
// construct this matrix based off of your existing containers
m_mat.push_back(m_lines[i] & m_cols[j]);
}
}
m_size = m_mat.size();
}
std::size_t size() const { return m_size; }
std::size_t sizeRows() const { return m_lineCount; }
std::size_t sizelColumns() const { return m_colsCount; }
std::vector<U>& getMatrix() const { return m_mat; }
std::vector<T>& getLines() const { return m_lines; }
std::vector<T>& getColumns() const { return m_columns; }
bool operator[]( std::size_t idx ) { return m_mat[idx]; }
const bool& operator[]( std::size_t idx ) const { return m_mat[idx]; }
};
int main() {
std::vector<unsigned> v1{ 1, 0, 1, 1, 0 };
std::vector<unsigned> v2{ 0, 1, 1, 1, 0 };
Matrix<unsigned, bool> mat1( v1, v2 );
int line = 0;
for ( unsigned u = 0; u < mat1.size(); ++u ) {
line++;
std::cout << mat1[u] << " ";
if ( line == mat1.sizeRows() ) {
std::cout << "\n";
line = 0;
}
}
std::cout << "\nPress any key to quit.\n" << std::endl;
_getch();
return 0;
}
Output
0 1 1 1 0
0 0 0 0 0
0 1 1 1 0
0 1 1 1 0
0 0 0 0 0
With this template class you can create a matrix of any type U by passing in two vectors for type T. Now how you construct the matrix will be implementation dependent. But this class is reusable for different types.
You could have two vectors of type doubles, and construct a matrix of unsigned chars, or you could have two vectors of user defined class or struct types and generate a matrix of unsigned values. This may help you out in many situations.
Note: - This does generate a compiler warning, no errors though and it prints and displays properly, but the compiler warning generated by MSVS 2015 is warning C4800: unsigned int: forcing value to bool true or false (performance warning)
This is generated for I am doing a bit wise & operation on to unsigned values; but that is why I set my initial vectors to be passed to this class template's constructor to have all 1s & 0s as this is meant for demonstration only.
EDIT - I made an edit to the class because I noticed I had a default constructor and had no way to add vectors to it, so I added an extra member variable, and an addVectors function, and moved the implementation from the defined constructor to the new function and just ended up calling that function in the defined constructor.
Creating an array isn't that difficult :)
A matrix (2D/3D/...-array) is unfortunately a little bit different if you want to do it your way!
But first of all you should know about the stack and the heap!
Lets have a look at these 2:
Stack:
A stack variable/array/matrix/... is only valid between the nearest 2 -> {} <- which you normally call a "codeblock". The size of it was defined during the "compile time" (the time where the compiler translates your code into the machine language). That means the size of your array needs to be set.
Example:
#include <iostream>
#define MACRO 128
int arraySize(int size){
std::cin >> size;
return size;
}
int main() {
//this is valid
int intArray[128] = {}; //the size(here: 128) needs to be a number like
//or a macro like 'MACRO' which is
//compile-time-only as well
//this is valid
int intArray2[MACRO] = {};
//this is not valid!
int intArray[size()] = {};
return 0;
}
Heap:
A heap variable/array/matrix/... is valid until you delete it. That also means that a heap var is created during the run-time(from starting your program until you close/stop it)! This is allows you to define it's size.
Example:
#include <iostream>
#define MACRO 128
int arraySize(int size){
return size;
}
int main() {
//this is valid
int intArray[128] = {}; //the size(here: 128) needs to be a number like
//or a macro like 'MACRO' whic is
//compile-time-only as well
//this is valid
int intArray2[MACRO] = {};
//creating an array with a non-static size
//works like this:
//int can also be a 'bool'
int* intArray = new int[arraySize()];
// ^ the star means you are pointing to
//an adress inside of your memory which has
//the size of an int (per element)
//That's why they are called "pointers"!
//Right now it points to the beginning of the
//array.
// ^ the keyword "new" says that
//you are allocating memory on the heap.
// ^
//then you have to say which kind of array
//it is which is the same you gave the pointer
// ^
//now you give it the size of that array
//this time it can be return value or the size
//of a variable
//as I mentioned...you have to delete this array on your own
//if you dont do that your program will crash
//maybe not after starting but it will!
//SO NEVER NEVER NEVER... forget about it
delete intArray[];
//^ write delete
// ^
//then the name of your array
// ^
//at the end of it write these 2 brackets
//thex say you wanna remove the whole array!
//why? because you can also create/delete
//heap variables not only arrays.
return 0;
}
Creating a matrix on the heap is unfortunately not that easy.
But it is essential to know how a 1D-array works before going to further dimensions! That's why I did this tutorial!
Klick here to see how to create a matrix on the heap
Klick here to learn more about the heap
Klick here to choose the best result of this theme
I hope I could help you :)!
I was trying to save the binary equivalent of a 32 bit number in an array A. For testing my showbits() function , I choosed 8,9 when I came across this thing:
I am facing an unreasonable thing in my code when I am placing memset in the function showbits(),I am geting absurd integers while I expect an output something as
00000000000000000000000000001000
that is the binary equivalent of 8 . While when I place memset in the main() method, it works properly and gives me the right output.Am I going out of bounds(I cannot see it !) .
My code :
SHOWBITS:
void showbits(int A[32],int num)
{
int k=0;
memset(A,0,sizeof(A));
while(num>0)
{
A[k] = num&1;
k++;
num>>=1;
}
return ;
}
Note: I have placed memset in showbits ,and I am getting incorrect answers!
MAIN:
int main()
{
int A[32],i;
showbits(A,8);
for(i=31;i>=0;i--)
printf("%d",A[i]);
return 0;
}
Whole program for testing:
#include<stdio.h>
#include<algorithm>
#include<cstring>
using namespace std;
void showbits(int A[32],int num)
{
int k=0;
memset(A,0,sizeof(A));
while(num>0)
{
A[k] = num&1;
k++;
num>>=1;
}
return ;
}
int main()
{
int A[32],i;
showbits(A,8);
for(i=31;i>=0;i--)
printf("%d",A[i]);
return 0;
}
When I place that memset statement in Main method before showbits() , I am getting correct output!
EDIT
If someone is interested in what I am getting
398420075242008462686872420075219611920941961187434-2205336646196127610926869242
68672826866724200752000202903316219611874341961187478819611565142686716196182637
61961141748268665201000
The A[32] in the method is actually just a pointer to A. Therefore, sizeof is the size of *int. Take the following test code:
void szof(int A[32])
{
std::cout << "From method: " << sizeof(A) << "\n";
}
int main(int argc, char *argv[])
{
int B[32];
std::cout << "From main: " << sizeof(B) << "\n";
szof(B);
return 0;
}
which give the following output:
From main: 128
From method: 8
Thus, the memset sets fewer bits than you think.
You must pass A by reference
void showbits(int (&A)[32],int num)
See here for more details: C++ pass an array by reference
Avi explained the problem in your code already. Another possible solution is to use C++-style arrays, instead of C-style arrays and memset. Then there is no possibility of a memset length error. Also there is no loss of performance.
#include <array>
void showbits(std::array<int, 32> &A, int num)
{
A = {}; // set all entries to 0
// ...
}
int main()
{
std::array<int, 32> A;
// ...
}
I need to fill a structure every 10 mS, in this strucure there are 230 variables, only bool and int. My thinking was first to fill and intialize randomly one by one all the variable. But it's very long to write and seems like very ugly code. Also this structure change often.
So my second thinking was to browse the structure ( maybe using a loop ? ) and fill randomly every variable.
After some research, I can't find anything. So, Is there a way to browse my structure and to fill the variable randomly ?
Thank you for your help.
EDIT : Here's what I try to do :
I've got a header file containing the structure :
typedef struct
{
/// Statut Ground-Flight
int _statutGroundFlight;
/// Statut Capteur de presence
bool _statutCapteurPrensence;
/// Statut Bouton OPEN in
bool _statutBoutonOpenIn;
/// Statut Bouton OPEN ext
bool _statutBoutonOpenExt;
/// Statut Bouton CLOSE in
bool _statutBoutonCloseIn;
/// Statut Bouton CLOSE ext
bool _statutBoutonCloseExt;
...
And here's what I want to do every 10 mS:
//Create a structure
struct myStruct;
//Browse the structure
for(int i; myStruct.size(); ++i){
if(myStruct[i] is int){
//Fill it randomly with int
}
if(mystruct[i] is bool){
//Fill it randomly with bool
}
}
I don't think there is a way to browse the structure and fill the variables as you want, but you can avoid writing codes by using macro.
You can write macro and let the pre-processor to generate the code for you ..
for example:
create one struct.def where you can define required fields
#ifndef INTEGER
#error "INTEGER not defined"
#endif
#ifndef BOOL
#error "BOOL not defined"
#endif
#ifndef create_struct
#error "create_struct not defined"
#endif
create_struct(my_struct,
INTEGER(i1)
BOOL(b1,false)
INTEGER(i2)
INTEGER(i3)
BOOL(b2,true)
BOOL(b3,false)
BOOL(b4,false)
INTEGER(i4)
//add or modify fields here
)
#undef INTEGER
#undef BOOL
#undef create_struct
Then write macro in your code by using above file
#include "stdio.h"
#include "string.h"
//create structure
#define INTEGER(var_name) int var_name;
#define BOOL(var_name,data) bool var_name;
#define create_struct(struct_id,data_type)\
typedef struct struct_id##_tag{\
data_type\
}struct_id;
#include "struct.def"
//-------------------------------------------
//function to initialize default value
#define INTEGER(var_name) p->var_name=0;
#define BOOL(var_name,data) p->var_name=data;
#define create_struct(struct_id,data_type)\
void initialize_##struct_id(struct_id* p)\
{\
data_type\
}
#include "struct.def"
//-------------------------------------------------
//function to fill random value to structure
#define INTEGER(var_name) p->var_name=rand();
#define BOOL(var_name,data) p->var_name=rand()%2;
#define create_struct(struct_id,data_type)\
void fill_random_##struct_id(struct_id* p)\
{\
data_type\
}
#include "struct.def"
//-----------------------------------------
Now if you run preprocessor then it will generate the below mentioned code for you....
typedef struct my_struct_tag{
int i1;
bool b1;
int i2;
int i3;
bool b2;
bool b3;
bool b4;
int i4;
}my_struct;
void initialize_my_struct(my_struct* p) {
p->i1=0;
p->b1=false;
p->i2=0;
p->i3=0;
p->b2=true;
p->b3=false;
p->b4=false;
p->i4=0;
}
void fill_random_my_struct(my_struct* p) {
p->i1=rand();
p->b1=rand()%2;
p->i2=rand();
p->i3=rand();
p->b2=rand()%2;
p->b3=rand()%2;
p->b4=rand()%2;
p->i4=rand();
}
Now, if you want to change your structure then you need to change in only one place that is in struct.def file
You can check the link http://rajenpandit.blogspot.in/p/using-macro.html for further details.
I would opt to use std::map to store values of your members.
class MyStructure
{
std::map< unsigned int, int > integerValues;
std::map< unsigned int, bool > booleanValues;
public:
bool & exampleBoolean = booleanValues[ 0 ];
int & exampleInteger = integerValues[ 0 ];
void randomIntegers() {
for( auto & integer : integerValues )
integer.second = randomInteger(); // put your favorite random here
}
};
This way you will change only the place data is actually stored, not the way that you have accessed your structure.
I would recommend making enum with field names to index a map.
An easy approach is to group the same-type fields, then create a union with type-specific arrays.
Example at ideone.com
#include <iostream>
using namespace std;
union X
{
struct
{
int i1, i2, i3;
bool b1, b2, b3;
};
struct
{
int is[3];
bool bs[3];
};
};
std::ostream& operator<<(std::ostream& os, const X& x)
{
os << "{ ";
for (int i = 0; i < 3; ++i)
os << x.is[i] << ' ' << x.bs[i] << ' ';
return os << '}';
}
int main()
{
for (int i = 0; i < 3; ++i)
{
X x;
for (int j = 0; j < 3; ++j)
{
x.is[j] = rand();
x.bs[j] = rand() % 2;
}
std::cout << x << '\n';
}
}
(Of course you should do something better than hard-coding the array dimensions wherever it's indexed, and allow the number of ints and bools to vary independently, but that's all trivial....)
Sample output:
{ 1804289383 0 1681692777 1 1957747793 1 }
{ 719885386 0 596516649 1 1025202362 1 }
{ 783368690 1 2044897763 0 1365180540 0 }
You cannot iterate over fields of a structure like you want.
If this is for a test, then you should not adapt the structure to suit the test. Instead, just do it the "hard" way - filling each field. This is also important because different fields certainly have different ways of being "random". For example _statutGroundFlight probably cannot be ANY integer value; it probably has a set of valid values to test.
I have to call one simple functions with different datatypes in c++. eg,
void Test(enum value)
{
int x;
float y; // etc
if(value == INT)
{
// do some operation on x
}
else if(value == float)
{
// do SAME operation on y
}
else if(value == short)
{
// AGAIN SAME operation on short variable
}
.
.
.
}
Thus I want to eliminate the repetitive code for different datatypes ...
So , I tried to use macro ,depending on values of enum, to define same variable for different datatypes .. but then not able to differentiate between the MACROS
e.g.
void Test(enum value)
{
#if INT
typedef int datatype;
#elif FLOAT
typedef float datatype;
.
.
.
#endif
datatype x;
// Do operation on same variable
}
But now every time the first condition #if INT is getting true.
I tried to set different values of macro to differentiate but not working :(
Can anyone help me achieve the above thing.
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
//type generic method definition using templates
template <typename T>
void display(T arr[], int size) {
cout << "inside display " << endl;
for (int i= 0; i < size; i++) {
cout << arr[i] << " ";
}
cout << endl;
}
int main() {
int a[10];
string s[10];
double d[10];
for (int i = 0; i < 10; i++) {
a[i] = i;
d[i] = i + 0.1;
stringstream std;
std << "string - "<< i;
s[i] = std.str();
}
display(a, 10); //calling for integer array
display(s, 10); // calling for string array
display(d, 10); // calling for double array
return 0;
}
If you really want your function to be generic, template is the way to go. Above is the way to do and call the method from main method. This might be of some help for you to reuse a function for different types. Pick up any tutorial or C++ books for complete understanding on templates and get a grip of the full concepts. Cheers.
You can use templates to achieve you purpose.
Simply write a template function which take the value in the function argument which is of generic type and put the operational logic inside it. Now call the function with different data types.
I advice you to use function overloading:
void foo(int arg) { /* ... */ }
void foo(long arg) { /* ... */ }
void foo(float arg) { /* ... */ }
Supposing you want do the same operation with integer and long types you can eliminate the code repetition in this way:
void foo(long arg) { /* ... */ }
void foo(int arg) { foo((long) arg); }
Lets say I have a function with prototype like this: int func(int * a), and it accepts an array as an argument.
How do I do this without the compiler showing errors everywhere: func({1,1,1,1})
Like this:
int func(int * a);
void somewhere_else()
{
int arr[4] = { 1, 1, 1, 1 };
func(arr);
}
Don't use raw arrays, and certainly don't pass pointers to them into functions. Ew! We're not in 1975 any more.
#include <cstddef>
#include <iostream>
#include <vector>
void func(std::vector<int> const& v) {
for (std::size_t i = 0; i < v.size(); i++)
std::cout << v[i] << " ";
}
int main() {
func({ 1, 2, 3, 4 });
}
// Output: "1 2 3 4 "
This requires a compiler that is compliant with certain features of C++11. Namely initializer lists.
You can use std::initializer_list:
int func(std::initializer_list<int> a) {
// do something with a here
}
Or you can write a wrapper that uses std::initializer_list (if for some reason you cannot change the original function):
int func_wrapper(std::initializer_list<int> a) {
std::vector<int> b = a;
func(b.data());
}
one way to do that would be
#include <iostream>
#include <stdio.h>
void abc (int *a,int z)
{
int m= z/sizeof(*a);
for(int i=0;i<m;i++)
{
std::cout<<"values " <<*a<<"\n";
a++;
}
}
int main()
{
int ar[]={11,12,13,14,15,1166,17};
std::cout << sizeof(ar)<<"size\n";
abc(ar,sizeof(ar));
getchar();
}
here in this case you dont need to worry about size and all. In case of
int ar[3]={1,2,3} that will give junk values if you try and search for NULL as
the third place is occupied by element 3
All you need is an (int[]) cast:
#include <iostream>
static void f (int* a) {
while (*a) std::cout << *a++ << "\n" ;
}
int main() {
f ((int[]){1,2,3,4,0}) ;
}
This code outputs
1
2
3
4
It works in C too -- see this ideone link.
Updated to add: I posted a new question about the legality of this construct, and Mat's answer is worth reading if you're interested in that kind of thing. Briefly, it seems that it is valid only in C99, but that some compilers allow it as an extension in all C/C++ variants.