Enum Array as parameter c++ - c++

I am new to c++ and I want to include an array of Enum values, and I am getting a syntax error in Microsoft Visual Studio. I am not sure why this is the case any help much appreciated. The error number is C2061 and it states "syntax error: identifier 'VerboseBinary'. Here is the code:
Header file verbose_binary.h
#pragma once
#include <bitset>
enum class VerboseBinary : int {
One,
Two,
Four,
Eight,
Sixteen,
Null,
};
void convert(std::bitset<5> bs, VerboseBinary aVB[6]);
verbose_binary.cpp
#include "verbose_binary.h"
#include "stdafx.h"
#include <bitset>
#include <string>
#include <iostream>
void convert(std::bitset<5> bs, VerboseBinary aVB[6]) {
VerboseBinary VBArray[6] = {
VerboseBinary:: One,
VerboseBinary:: Two,
VerboseBinary:: Four,
VerboseBinary:: Eight,
VerboseBinary:: Sixteen,
VerboseBinary:: Null
};
for (int i = 0; i < 5; i++) {
if (bs.test(i)) {
aVB[i] = VBArray[i];
}
else {
aVB[i] = VerboseBinary::Null;
}
}
aVB[5] = VerboseBinary::Null;
}
Main
#include "stdafx.h"
#include <iostream>
#include <iostream>
#include <bitset>
#include "verbose_binary.h"
int main() {
int a, b;
std::bitset<5> aBs, bBs;
std::cout << "Enter two numbers between 0-31:" << std::endl;
std::cin >> a >> b;
if (a<0 || a>31) return -1;
if (b<0 || b>31) return -2;
aBs = static_cast<std::bitset<5>>(a);
bBs = static_cast<std::bitset<5>>(b);
// std::cout << aBs << " " << bBs << std::endl;
VerboseBinary aVB[6];
VerboseBinary bVB[6];
convert(aBs, aVB);
convert(bBs, bVB);
return 0;
}

Lol, so it looks like one of these issues was resposible for the error:
What version of Visual Studio are you using? enum with class became available with VS 2012.
Also, there is a stray comma at the end of your enum's definition.
Also, stdafx.h should appear before any other includes in verbose_binary.cpp.
Main has a benign double-inclusion for <iostream>

Related

C++ alternative to singleton design when a function-only class needs to be initialize at least once?

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>
#include <random>
#include <map>
#include <math.h>
#include <cstring>
using namespace std;
class MathClass {
private:
size_t current_capacity;
double* logfact;
bool inited = false;
MathClass() {
current_capacity = 0;
logfact = new double[1];
logfact[0] = 0;
}
void calculateLogFact(int n) {
if (current_capacity >= n) return;
double* newLogfact = new double[n+1];
for (int i=0; i<=current_capacity; i++) newLogfact[i] = logfact[i];
for (int i=current_capacity+1; i<=n; i++) newLogfact[i] = newLogfact[i-1] + log(double(i));
delete[] logfact;
logfact = newLogfact;
}
double factorial(int n) {
cout << "n = " << n << "\n";
calculateLogFact(n);
for (int i=0; i<=n; i++) cout << int64_t(round(exp(logfact[i]))) << " ";
cout << "\n";
return exp(logfact[n]);
}
public:
static double factorial2n(int n) {
static MathClass singleton;
return singleton.factorial(2*n);
}
};
int main(int argc, char** argv)
{
cout << MathClass::factorial2n(10) << "\n";
return 0;
}
My library need to use an expensive function that needs to be initialized once before use (to pre-calculate some expensive values so that we don't have to calculate them every time). Currently, I use the singleton method above for this.
However, there are 2 problems:
Multi-threading: this will cause race conditions if 2 different threads call this function.
People don't like singleton
Other problems that I'm not aware of
What other design can I use to solve this problem? Pre-computing values is a must since this function needs to be fast.
I agree with comments: Why hide the fact that MathClass caches results from the user? I, as a potential user, see no real benefit, rather potential confusion. If I want to reuse previously cached results stored in an instance I can do that. You need not wrap the whole class in a singleton for me to enable that. Also there is no need to manually manage a dynamic array when you can use std::vector.
In short: The alternative to using a singleton is to not use a singleton.
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>
#include <random>
#include <map>
#include <math.h>
#include <cstring>
using namespace std;
class MathClass {
private:
size_t current_capacity;
std::vector<double> logfact;
bool inited = false;
void calculateLogFact(int n) {
if (logfact.size() >= n) return;
auto old_size= logfact.size();
logfact.resize(n);
for (int i=old_size; i<n; i++) logfact.push_back(logfact.back() + log(double(i)));
}
double factorial(int n) {
cout << "n = " << n << "\n";
calculateLogFact(n);
for (int i=0; i<=n; i++) cout << int64_t(round(exp(logfact[i]))) << " ";
cout << "\n";
return exp(logfact[n]);
}
public:
MathClass() {
logfact.push_back(0);
}
double factorial2n(int n) {
return factorial(2*n);
}
};
void foo(MathClass& mc) { // some function using previously calculated results
std::cout << mc.factorial2n(2);
}
int main(int argc, char** argv)
{
MathClass mc;
cout << mc.factorial2n(10) << "\n";
foo(mc);
}
I am not sure if the maths is correct, I didn't bother to check. Also inited and most of the includes seem to be unused.
Concerning "Multi-threading: this will cause race conditions if 2 different threads call this function." I would also not bother too much to bake the thread-safety into the type itself. When I want to use it single-threaded I do not need thread-safety, and I don't want to pay for it. When I want to use it multi-threaded, I can do that by using my own std::mutex to protect access to the mc instance.
PS: Frankly, I think the whole issue is caused by a misconception. Your MathClass is not a "function only" class. It is a class with state and member functions, just like any other class too. The "misconception" is to hide the state from the user and pretend that there is no state when in fact there is state. When using this class I would want to be in conctrol what results I can query because they are already cached and which results need to be computed first. In other words, I would provide more access to the class state, rather than less.

structuring classes for a tic-tac-toe(c++)

I have been learning c++ with 'C++ Programming for
the Absolute Beginner' which have been very useful, whoever when it comes to OOP and splitting the classes into different files it doesn't explain it very well.
This is the code I have, I didn't put everything here, just the problematic stuff. The weird thing is that if I exclude Juego.h and Juego.cpp from the project it lets me build it, but if I include it I get the following errors:
jugador.h(8): error C2146: syntax error : missing ';' before identifier 'c_o'
jugador.h(8): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
jugador.h(9): error C2061: syntax error : identifier 'casilla'
juego.cpp(15): error C2039: 'c_o' : is not a member of 'Jugador'
jugador.h(5) : see declaration of 'Jugador'
Because it only happens with Juego.h in the code I think the problem is that I didn't structure well the header files. I have been able to solve many of the problems searching on google but I can't fix those, I even get syntax errors.
//Jugador.h
#include <string>
using std::string;
class Jugador
{
public:
string p_name;
//casilla is X,O or blankspace, done using enum in Tablero.h( it have to be in a cpp file)
casilla c_o;
Player(string name, casilla marca);
void turno(Tablero* tabla);
};
//Jugador.cpp
#include "Jugador.h"
#inlcude "Tablero.h"
#include <string>
using std::string;
Jugador::Jugador(string nombre,casilla marca): p_name(nombre), c_o(marca) {}
void Jugador::turno(Tablero* tabla)
{
using std::cout;
using std::cin;
int fil;
int col;
do
{
cout << p_name.c_str() <<" en que fila quieres jugar(1-2-3)?\n";
cin >> fil;
cout<<p_name.c_str() <<" en que columna quieres jugar(1-2-3)?\n";
cin >> col;
}while(tabla->tab[fil-1][col-1]==vacia);
tabla->tab[fil-1][col-1]=c_o;
}
//Juego.h
class Jugador;
class Tablero;
class Juego
{
public:
Juego(void);
bool ganador(Jugador* player, Tablero* tabla);
bool fin(Tablero* tabla);
};
//Juego.cpp
#include "Juego.h"
#include "Jugador.h"
#include "Tablero.h"
Juego::Juego() {}
bool Juego::ganador(Jugador* player, Tablero* tabla)
{
using std::cout;
using std::cin;
casilla marca_jug = player->c_o;
bool winner = false;
//...
// if-else structure which set winner to true if the conditons to win are achived
if (winner)
cout<<player->p_name.c_str()<<" ha ganado!!!!\n";
return winner;
}
//if there isnt any blank square, ends the game
bool Juego::fin(Tablero* tabla)
{
bool fin_juego=false;
for(int fil=0; fil<3; fil++)
{
for(int col=0; col<3; col++)
{
if(tabla->tab[fil][col]==vacia)
fin_juego=true;
}
}
return fin_juego;
}
As I said it isn't the whole code, I wasnt to have more things that needed just to make everything clearer I'm gonna add tablero.h
Here is were casilla is defined. Casilla is a 2D array:
//Tablero.h
#include <iostream>
#include <string>
enum casilla {vacia,X,O};
class Tablero
{
public:
casilla tab[3][3];
Tablero(void);
void draw(void);
};
//Tablero.cpp
#include "Tablero.h"
Tablero::Tablero(void)
{
using std::cout;
casilla tab[3][3];
for(int f=0;f<3;f++)
{
for (int c= 0;c<3;c++)
{
tab[f][c]=vacia;
}
}
}
void Tablero::draw(void)
{
using std::cout;
using std::string;
for(int f=0;f<3;f++)
{
for (int c= 0;c<3;c++)
{
string s;
if (c!=2)
{
switch (tab[f][c])
{
case vacia: s=" "; break;
case X: s="X"; break;
case O: s="O";break;
}
cout << s.c_str() <<" | ";
}
else
{
switch (tab[f][c])
{
case vacia: s=" "; break;
case X: s="X"; break;
case O: s="O"; break;
}
cout << s.c_str() <<"\n";
}
}
}
}
Let us look at the first error.
//Jugador.h
#include <string>
using std::string;
class Jugador
{
public:
string p_name;
//casilla is X,O or blankspace, done using enum in Tablero.h( it have to be in a cpp file)
casilla c_o;
At this moment, the compiler does not know what a casilla is. Perhaps it is in some other file which has to be included, too, before any use of it:
//Jugador.h
#include <string>
#include <where-casilla-is-from>
using std::string;
...

Error C3861: 'ResGain': identifier not found

essentially I'm writing a short script. The easiest way to look at is that it's for a game with a resource collection. ResGain is the resources gained, and BonusGain is the chance to earn an extra resource. I am getting Identifier not found errors for the ResGain and Bonus Gain functions, but I have declared the ResGain and BonusGain functions before main. Any ideas why?
#include <iostream>
#include <cstdlib>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
float ResGain(float u, int r) //calc Base resource Gain
{
float lapout;
lapout = r * u;
return (lapout);
}
char BonusGain(int b) //Determines if a bonus material would be produced.
{
char bonus;
int rng;
rng = rand() % 100 + 1;
if (rng <= b)
bonus = 1;
return(bonus);
}
int main()
{
float l;
l = ResGain(1.1,70);
cout << "You have earned" << l << "Lapis";
if (BonusGain(3)==1)
cout << "You have also earned a bonus material";
system("pause");
return 0;
}
Most probably the identifier not found is system() which is not part of the standard library. You should locate the Windows-specific header where it is declared.

Unusual Declaration Error

This seems like a really easy fix, but I can't understand what it's coming from.
Any help fully appreciated!
The following 2 lines of code produce the following errors respectively.
vector <spades::player> players(4, player());
vector <spades::card> deck(52,card());
error: 'player' was not declared in this scope
error: 'card' was not declared in this scope
Below is my card.cpp
#include <iostream>
#include <sys/ioctl.h>
#include <cstdio>
#include <unistd.h>
#include <locale.h>
#include <ncursesw/ncurses.h>
#include "card.h"
namespace spades {
card::card()
{
cardSuit = 0;
cardNum = 0;
}
card::card(int suit, int number)
{
cardSuit = suit;
cardNum = number;
}
}
Below is my player.cpp
#include <iostream> // Stream declarations
#include <vector> //Vectors used to store deck and players hands
#include <string> //String declarations
#include <algorithm> //Shuffle Method
#include <sys/ioctl.h>
#include <cstdio>
#include <unistd.h>
#include <locale.h>
#include <ncursesw/ncurses.h>
#include "player.h"
namespace spades {
using namespace std;
player::player() {
score =0; //total score
bid = NULL; //bid for that round
tricksTaken = 0; //score for thast round
sandBag = 0; //the number of points you win, more than what you bid, every 10th bag = -100
doubleNil = false;
for(int i=0; i<13; i++)
hand.push_back(card());
}
void player::addCard(spades::card b){
for (int i=0; i<hand.size(); i++){
//compare card being played to the ones in your hand to search and determine which one to erase
if((hand.at(i).getCardNum() == 0) &&
(hand.at(i).getSuit() == 0))
{
hand.at(i).setCardNum(b.getCardNum());
hand.at(i).setSuit(b.getSuit());
return;
}
}
}
void player::removeCard(spades::card a) {
for (int i=0; i<hand.size(); i++){
//compare card being played to the ones in your hand to search and determine which one to erase
if((hand.at(i).getCardNum() == a.getCardNum()) &&
(hand.at(i).getSuit() == a.getSuit()))
{
hand.at(i).setCardNum(0);
hand.at(i).setSuit(0);
return;
}
}
}
}
The compiler is actually complaining about the arguments you pass to vector constructors. You specified player() and card() in the constructor arguments, while it is obvious that your types are actually named spades::player and spades::card. You correctly specified the spades:: part in template parameters. Why did you omit the spades:: part from the constructor arguments?
It should be
vector <spades::player> players(4, spades::player());
vector <spades::card> deck(52, spades::card());
It should be noted though that the explicit argument is unnecessary, so you can just do
vector <spades::player> players(4);
vector <spades::card> deck(52);
and get the same result.
Also you don't need the
namespace spades {
}
block in player.cpp, only around you class definition in the header file.
Maybe you ment
using namespace spades;

Struct defined in header and included in two source codes is only defined in one

I have a struct defined in a header file with three other files that #include that header file. One is another header(queue.h) file that defines a very basic hash table and the other two are source codes where one is defining the functions from the hash table header(queue.cpp) and the other contains main(p2.cpp).
The problem that I'm having is that the struct seems to work fine in p2.cpp but in queue.h the compiler is telling me that the struct is undefined.
Here is p2.h containing the struct definition.
#ifndef __P2_H__
#define __P2_H__
#define xCoor 0
#define yCoor 1
#include <iostream>
#include <string>
#include "queue.h"
#include "dlist.h" //linked list which I know works and is not the problem
using namespace std;
struct spot {
float key[2];
string name, category;
};
#endif /* __P2_H__ */
I have queue.h included in this header so that I only have to include p2.h in p2.cpp.
Here is p2.cpp
#include <iostream>
#include <string>
#include <iomanip>
#include "p2.h"
using namespace std;
int main () {
cout << fixed;
cout << setprecision (4);
Queue hashTable;
spot *spot1 = new spot;
spot1->key[xCoor] = 42.2893;
spot1->key[yCoor] = -83.7391;
spot1->name = "NorthsideGrill";
spot1->category = "restaurant";
hashTable.insert(spot1);
Dlist<spot> test = hashTable.find(42.2893, -83.7391);
while (!test.isEmpty()) {
spot *temp = test.removeFront();
cout << temp->key[xCoor] << " " << temp->key[yCoor] << " " << temp->name << " " << temp->category << endl;
delete temp;
}
return 0;
}
Places and item in the hash table and takes it back out.
Here is queue.h
#ifndef __QUEUE_H__
#define __QUEUE_H__
#include <iostream>
#include <string>
#include "dlist.h"
#include "p2.h"
using namespace std;
class Queue {
// OVERVIEW: contains a dynamic array of spaces.
public:
// Operational methods
bool isEmpty();
// EFFECTS: returns true if list is empy, false otherwise
void insert(spot *o);
// MODIFIES this
// EFFECTS inserts o into the array
Dlist<spot> find(float X, float Y);
// Maintenance methods
Queue(); // ctor
~Queue(); // dtor
private:
// A private type
int numInserted;
int maxElts;
Dlist <spot>** queue;
// Utility methods
//Increases the size of the queue.
void makeLarger();
int hashFunc(float X, float Y, int modNum);
};
#endif /* __QUEUE_H__ */
Here is queue.cpp
#include <iostream>
#include <string>
#include <cstdlib>
#include "queue.h"
using namespace std;
bool Queue::isEmpty() {
return !numInserted;
}
void Queue::insert(spot *o) {
if (numInserted >= maxElts) {
makeLarger();
}
int index = hashFunc(o->key[xCoor], o->key[yCoor], maxElts);
queue[index] -> insertFront(o);
}
Queue::Queue() {
numInserted = 0;
maxElts = 1000;
queue = new Dlist<spot>*[maxElts];
for (int i = 0; i < maxElts; i++) {
queue[i] = new Dlist<spot>;
}
}
Queue::~Queue() {
for (int i = 0; i < maxElts; i++) {
delete queue[i];
}
delete[] queue;
}
void Queue::makeLarger() {
Dlist <spot>** temp = queue;
queue = new Dlist <spot>*[maxElts*2];
for (int i = 0; i < maxElts*2; i++) {
queue[i] = new Dlist<spot>;
}
for (int i = 0; i < maxElts; i++) {
while (!temp[i] -> isEmpty()) {
spot *spotTemp = temp[i] -> removeFront();
int index = hashFunc(spotTemp->key[xCoor], spotTemp->key[yCoor], maxElts*2);
queue[index] -> insertFront(spotTemp);
}
}
for (int i = 0; i < maxElts; i++) {
delete temp[i];
}
delete[] temp;
maxElts *= 2;
}
int Queue::hashFunc(float X, float Y, int modNum) {
return ((int)(10000*X) + (int)(10000*Y))%modNum;
}
Dlist<spot> Queue::find(float X, float Y) {
Dlist<spot> result;
Dlist<spot> *temp = new Dlist<spot>;
int index = hashFunc(X, Y, maxElts);
while (!queue[index] -> isEmpty()) {
spot *curSpot = queue[index] -> removeFront();
if ((curSpot->key[xCoor] == X) && (curSpot->key[yCoor] == Y)) {
result.insertFront(new spot(*curSpot));
}
temp -> insertFront(curSpot);
}
delete queue[index];
queue[index] = temp;
return result;
}
I believe that the problem is in my queue.h file because it's where I get all of the errors like "spot has not been declared". Every time spot appears in queue.h I have at least one error. I searched around for anything like this but all I could find was people trying to share one instance of a struct across multiple source files, or the obvious question of putting a struct in a header and including that header across multiple source files(which is what I'm doing but my problem seems to be a rather unique one).
You are including queue.h within the header that actually defines spot, so by the point the file is actually included spot has not been defined yet.
For your scope guards, note that identifiers starting with a double underscore are reserved by the implementation, don't use them.
And this is a poor choice even in plain C:
#define xCoor 0
#define yCoor 1
use this instead:
enum {
xCoor = 0
, yCoor = 1
};
Ok first never ever using "using" clauses in header files (it destroys the purposes of namespaces)
2nd provide a complete example that fails to compile
In addition to what others have said, you also have a circular reference error, which can also lead to similar undefined symbol errors. You have queue.h include p2.h, which includes queue.h.