The following code:
std::vector< int > keysDown;
for each ( int currentKey in keysDown )
{
}
is throwing an intellisense error:
1 IntelliSense: a 'for each' statement cannot operate on an expression of type "std::vector<int, std::allocator<int>>"
but it seems to compile and run, any ideas?
does not seem to iterate through the vector:
void Keyboard::AddKeyToVector( int key )
{
keysDown.push_back( key );
}
void Keyboard::RemoveKeyFromVector( int key )
{
std::vector< int > keysDown; // Placing this here for brevity, it's declared in the class's .h and is instanciated globally
int i;
for( int currentKey : keysDown )
{
if( currentKey == key )
{
keysDown.erase(keysDown.begin()+i);
}
i++;
}
}
Related
I have a struct of slotAndId struct, which is declared like so
typedef struct {
int slot;
int id;
} slotAndId;
Then I have a vector which holds many objects of type slotAndId...
slotAndId object;
vector<slotAndId> ids;
for (int i = 0; i < 20; i++) {
object.slot = i;
object.id = i + 2000; //random id as example, this will be generated by something else in reality.
ids.push_back(object);
}
If I then wanted to find, for example, if there's a slotAndId object which has slot equal to 20 within the vector, how would I do that in C++98? How would I then be able to delete that specific slotAndId object from the vector?
This is what std::find_if is for.
bool HasSlot20(const slotAndId& item)
{
return item.slot == 20;
}
int main()
{
std::vector<slotAndId> ids = {..};
std::vector<slotAndId>::const_iterator it = std::find_if(
ids.begin(),
ids.end(),
HasSlot20
);
}
We need the extra function because C++98 doesn't have lambdas, but we can make it more flexible by using a functor instead:
struct HasSlot
{
HasSlot(const int id) : m_id(id) {}
bool operator()(const slotAndId& item)
{
return item.slot == m_id;
}
private:
const int m_id;
};
int main()
{
std::vector<slotAndId> ids = {..};
std::vector<slotAndId>::const_iterator it = std::find_if(
ids.begin(),
ids.end(),
HasSlot(20)
);
}
or:
int main()
{
HasSlot finder(20);
std::vector<slotAndId> ids = {..};
std::vector<slotAndId>::const_iterator it = std::find_if(
ids.begin(),
ids.end(),
finder
);
}
Now this logic is re-usable with different parameters.
Alternatively just have a loop!
If your container is very large, you might consider a different (or additional) data structure that can do this in better than linear time.
I am having this problem for a while now and I can't see an obvious solution .
I am trying to compile a program and I am getting an error on the following
part of code :
class entry
{
private:
int node_id ;
int toll[2] ;
public:
entry( int );
~entry( void );
int get_node_name( void ){ return node_id; };
int* get_toll( void ){ return toll ; };
int* get_etoll( void ){ return etoll ; };
void entry_operate() ;
};
entry::entry( int id)
{
node_id = id ;
for ( int i = 0 ; i < 2 ; i++ )
{
toll[i] = 0 ;
etoll[i] = 0 ;
}
}
entry::~entry()
{
}
entry::entry_operate()
{
}
Error:
[Error] ISO C++ forbids declaration of 'entry_operate' with no type [-fpermissive]
[Error] prototype for 'int entry::entry_operate()' does not match any in class 'entry'
[Error] candidate is: void entry::entry_operate()
You need to specify the full function type:
void entry::entry_operate() { /* ... */ }
I know that (at least in C++ and I assume anytime it's used) argv[0] refers to the file path as the program is usually the first argument listed there. For the project I'm working on for class, I've made a class that handles the command line (as far as the constraints of the project, we're making a project that can read in text files and count uniqueness of words)
SO I'll stop blabbing and get to the question - in my command line class I would like a method to "return argv[0];" but saying that implicitly in a method didn't work. Here's my code for the headerfile, and the class:
CmdLine.h
#pragma once
#include<string>
#include<algorithm>
class CmdLine
{
public:
CmdLine( int argc, char* argv[] );
~CmdLine();
std::string getFile ( int index );
int getNumFiles ( void );
std::string getFlag ( int index );
int getNumFlags( void );
bool isFlag ( char c );
std::string getCommandPath ( );
private:
int myArgc;
char** myArgv;
int myNumFiles;
std::string myFileNames[ 100 ];
int myNumFlags;
std::string myFlags[ 100 ];
private:
CmdLine( const CmdLine& other );
CmdLine& operator=( const CmdLine& rhs );
};
CmdLine.cpp:
#include <iostream>
#include <string>
#include "CmdLine.h"
using namespace std;
CmdLine::CmdLine(int argc, char *argv[])
{
myArgc = argc;
myArgv = argv;
myNumFiles = 0;
myNumFlags = 0;
for ( int i = 1; i < argc ; i++ )
{
std::string arg = argv[i];
if ( arg[0] == '/' )
{
myFlags[ myNumFlags++ ] = argv[i];
}
else
{
myFileNames[ myNumFiles++ ] = argv[i];
}
}
}
CmdLine::~CmdLine()
{}
int CmdLine::getNumFiles ( void )
{
return myNumFiles;
}
string CmdLine::getFile ( int index )
{
//Check to see if index < number of files
return myFileNames[ index ];
}
int CmdLine::getNumFlags ( void )
{
return myNumFlags;
}
string CmdLine::getFlag( int index )
{
return myFlags[ index ];
}
//string CmdLine::getCommandPath ( )
//{
// return
//}
For my CS assignment, we were to implement a binary heap to replace the STL priority queue on her working program, that was the first part. For the second part, we have to re-implement it using polymorphism. I finished the first part, and all I did was divide all classes into its own header and source file, and I get a massive amount of error. On xcode it says unknown type name 'Event'.
I tried changing the #ifndef stuff ( sorry I don't know what it's called ), but no luck.
Any help would be appreciated, thank you.
David
I'm using xcode, but here's the error message from Terminal:
In file included from ModemSimV2.h:5,
from Event.h:4,
from Event.cpp:1:
EventHeap.h:18: error: expected ‘,’ or ‘...’ before ‘&’ token
EventHeap.h:18: error: ISO C++ forbids declaration of ‘Event’ with no type
EventHeap.h:19: error: ISO C++ forbids declaration of ‘Event’ with no type
EventHeap.h:19: error: expected ‘;’ before ‘*’ token
EventHeap.h:23: error: ISO C++ forbids declaration of ‘Event’ with no type
EventHeap.h:23: error: expected ‘;’ before ‘*’ token
In file included from Event.h:4,
from EventHeap.h:8,
from EventHeap.cpp:1:
ModemSimV2.h:11: error: ‘EventHeap’ has not been declared
ModemSimV2.h:23: error: ISO C++ forbids declaration of ‘EventHeap’ with no type
ModemSimV2.h:23: error: expected ‘;’ before ‘*’ token
EventHeap.cpp: In constructor ‘EventHeap::EventHeap()’:
EventHeap.cpp:6: error: call of overloaded ‘Event()’ is ambiguous
Event.h:10: note: candidates are: Event::Event(int, int)
Event.h:9: note: Event::Event()
EventHeap.cpp: In constructor ‘EventHeap::EventHeap(int)’:
EventHeap.cpp:12: error: call of overloaded ‘Event()’ is ambiguous
Event.h:10: note: candidates are: Event::Event(int, int)
Event.h:9: note: Event::Event()
EventHeap.cpp: In member function ‘void EventHeap::buildHeap(int)’:
EventHeap.cpp:40: error: call of overloaded ‘Event()’ is ambiguous
Event.h:10: note: candidates are: Event::Event(int, int)
Event.h:9: note: Event::Event()
main.cpp:
#include <queue>
#include <vector>
#include <functional> // for greater()
#include <climits> // for INT_MAX
#include <iostream>
#include "random.h"
#include "ModemSimV2.h"
#include "Event.h"
#include "EventHeap.h"
using namespace std;
// Simple main to test ModemSim class.
int main( )
{
int numModems;
int totalTime;
double avgConnectTime;
int dialInFrequency;
cout << "Enter number of modems, length of simulation,\n"
<< " average connect time, how often calls occur: ";
cin >> numModems >> totalTime >>
avgConnectTime >> dialInFrequency;
EventHeap eHeap( numModems );
ModemSimV2 s( numModems, avgConnectTime, dialInFrequency, eHeap );
s.runSim( totalTime );
return 0;
}
Event.h:
#ifndef EVENT_P2_H
#define EVENT_P2_H
#include "ModemSimV2.h"
class Event{
//enum { DIAL_IN = 1, HANGUP = 2 };
public:
Event( );
Event( int name = 0, int tm = 0 );
bool operator > ( const Event & rhs ) const;
bool operator < ( const Event & rhs ) const;
bool operator <= ( const Event & rhs ) const;
bool operator != ( const Event & rhs ) const;
//void process( ModemSimV2 m );
friend class ModemSimV2;
private:
int who; // the number of the user
int time; // when the event will occur
int what; // DIAL_IN or HANGUP
};
/*
class Dialin : public Event{
public:
Dialin( );
void process( ModemSimV2 m );
};*/
#endif
Event.cpp:
#include "Event.h"
Event::Event( ) {
}
Event::Event( int name, int tm )
: time( tm ), who( name ) {
return;
}
bool Event::operator > ( const Event & rhs ) const {
return time > rhs.time;
}
bool Event::operator < ( const Event & rhs ) const {
return time < rhs.time;
}
bool Event::operator <= ( const Event & rhs ) const {
return time < rhs.time;
}
bool Event::operator != ( const Event & rhs ) const {
return time != rhs.time;
}
EventHeap.h:
#ifndef BINARY_HEAP_P2_H
#define BINARY_HEAP_P2_H
#include <iostream>
#include <cmath>
#include <vector>
#include "Event.h"
class EventHeap{
public:
EventHeap( );
EventHeap( int numIndex );
bool empty( ) const;
const int & findMin( ) const;
void push( const Event & x );
Event * pop();
private:
int size; // Number of elements in heap
Event *array; // The heap array
void buildHeap( int index );
void reIndex( int hole );
int getLeft( int index ) const;
int getRight( int index )const;
int getParent( int index )const;
};
#endif
EventHeap.cpp:
#include "EventHeap.h"
//Constructor
EventHeap::EventHeap( ) {
array = new Event[1];
size = 0;
}
EventHeap::EventHeap( int numVals ) {
array = new Event[numVals];
size = 0;
}
//insert
void EventHeap::push( const Event &e ) {
array[size] = e;
reIndex( size );
size++;
}
//removes the min val
Event* EventHeap::pop( ) {
Event *e = &array[0];
array[0] = array[size - 1];
size--;
if( !empty( ) )
buildHeap(0);
return e;
}
//re do
void EventHeap::buildHeap( int nodeIndex ) {
int leftChildIndex, rightChildIndex, minIndex;
Event tmp;
leftChildIndex = getLeft(nodeIndex);
rightChildIndex = getRight(nodeIndex);
if (rightChildIndex >= size) {
if (leftChildIndex >= size)
return;
else
minIndex = leftChildIndex;
} else {
if (array[leftChildIndex] <= array[rightChildIndex])
minIndex = leftChildIndex;
else
minIndex = rightChildIndex;
}
if (array[nodeIndex] > array[minIndex]) {
tmp = array[minIndex];
array[minIndex] = array[nodeIndex];
array[nodeIndex] = tmp;
buildHeap(minIndex);
}
}
//re index
void EventHeap::reIndex( int hole ) {
while( array[hole] != NULL && array[hole] < array[getParent( hole )] ) {
int pIndex = getParent( hole );
Event temp( array[hole] );
array[hole] = array[pIndex];
array[pIndex] = temp;
hole = pIndex;
}
}
//is Empty
bool EventHeap::empty() const {
return ( size == 0 );
}
int EventHeap::getLeft( int index ) const {
return ( index * 2 ) + 1;
}
int EventHeap::getRight( int index ) const {
return ( index * 2 ) + 2;
}
int EventHeap::getParent( int index ) const {
return ( index - 1 ) / 2;
}
ModemSimV2.h
#ifndef MODEM_SIM_V2_H
#define MODEM_SIM_V2_H
#include "Event.h"
#include "EventHeap.h"
#include "random.h"
class ModemSimV2{
public:
ModemSimV2( int modems, double avgLen, int callIntrvl, EventHeap e );
// Add a call to eventSet at the current time,
// and schedule one for delta in the future.
void nextCall( int delta );
// Run the simulation
void runSim( int stoppingTime );// = INT_MAX );
// friend class Event;
private:
Random r; // A random source
EventHeap *eventSet; // Pending events
// Basic parameters of the simulation
int freeModems; // Number of modems unused
const double avgCallLen; // Length of a call
const int freqOfCalls; // Interval between calls
};
#endif
ModemSimV2.cpp
#include "ModemSimV2.h"
// Constructor for ModemSim.
ModemSimV2::ModemSimV2( int modems, double avgLen, int callIntrvl, EventHeap e )
: freeModems( modems ), avgCallLen( avgLen ),
freqOfCalls( callIntrvl ), r( (int) time( 0 ) )
{
eventSet = &e;
nextCall( freqOfCalls ); // Schedule first call
}
// Place a new DIAL_IN event into the event queue.
// Then advance the time when next DIAL_IN event will occur.
// In practice, we would use a random number to set the time.
void ModemSimV2::nextCall( int delta ){
static int nextCallTime = 0;
static int userNum = 0;
eventSet->push( Event( userNum++, nextCallTime ) );
nextCallTime += delta;
}
// Run the simulation until stopping time occurs.
void ModemSimV2::runSim( int stoppingTime ){
Event *e;
while( !eventSet->empty( ) ){
e = eventSet->pop();
if ( e->time > stoppingTime )
break;
//e->process( this );
nextCall( freqOfCalls );
}
}
Event.h includes ModemSimV2.h. ModemSimV2.h includes Event.h. That's not going to work without a little help.
You should read up on forward declarations. See this StackOverflow question for more information.
I have a 3D multi_array and I would like to make 2D slices using dimensions specified at runtime. I know the index of degenerate dimension and the index of a slice that I want to extract in that degenerate dimension. Currently the ugly workaround looks like that:
if (0 == degenerate_dimension)
{
Slice slice = input_array[boost::indices[slice_index][range()][range()]];
}
else if (1 == degenerate_dimension)
{
Slice slice = input_array[boost::indices[range()][slice_index][range()]];
}
else if (2 == degenerate_dimension)
{
Slice slice = input_array[boost::indices[range()][range()][slice_index]];
}
Is there a more beautiful way to construct index_gen object?
Something like that:
var slicer;
for(int i = 0; i < 3; ++i) {
if (degenerate_dimension == i)
slicer = boost::indices[slice_index];
else
slicer = boost::indices[range()];
}
Slice slice = input_array[slicer];
It seems each subsequent call to boost::indices::operator[] returns a different type depending on the dimensionality (i.e. number of previous calls), so there's no way to use a single variable, that can hold the temporary index_gen object.
Please, try this. Сode has one disadvantage - it refers to ranges_ array variable declared at boost::detail:: multi_array namespace.
#include <boost/multi_array.hpp>
typedef boost::multi_array<double, 3> array_type;
typedef boost::multi_array_types::index_gen::gen_type<2,3>::type index_gen_type;
typedef boost::multi_array_types::index_range range;
index_gen_type
func(int degenerate_dimension, int slice_index)
{
index_gen_type slicer;
int i;
for(int i = 0; i < 3; ++i) {
if (degenerate_dimension == i)
slicer.ranges_[i] = range(slice_index);
else
slicer.ranges_[i] = range();
}
return slicer;
}
int main(int argc, char **argv)
{
array_type myarray(boost::extents[3][3][3]);
array_type::array_view<2>::type myview = myarray[ func(2, 1) ];
return 0;
}
What you're trying to do is move a variable from run time to compile time. This can only be done with a chain of if else statements or a switch statement.
A simplified example
// print a compile time int
template< int I >
void printer( void )
{
std::cout << I << '\n';
}
// print a run time int
void printer( int i )
{
// translate a runtime int to a compile time int
switch( i )
{
case 1: printer<1>(); break;
case 2: printer<2>(); break;
case 3: printer<3>(); break;
case 4: printer<4>(); break;
default: throw std::logic_error( "not implemented" );
}
}
// compile time ints
enum{ enum_i = 2 };
const int const_i = 3;
constexpr i constexper_i( void ) { return 4; }
// run time ints
extern int func_i( void ); // { return 5; }
extern int global_i; // = 6
int main()
{
int local_i = 7;
const int local_const_i = 8;
printer<enum_i>();
printer<const_i>();
printer<constexpr_i()>();
//printer<func_i()>();
//printer<global_i>();
//printer<local_i>();
printer<local_const_i>();
printer( enum_i );
printer( const_i );
printer( constexpr_i() );
printer( func_i() ); // throws an exception
printer( global_i ); // throws an exception
printer( local_i ); // throws an exception
printer( local_const_i ); // throws an exception
}