this is the header definition.
#ifndef ENTITY_H
#define ENTITY_H
//------------------------------------------------------------------------
//
// Name: BaseGameEntity.h
//
// Desc: Base class for a game object
//
// Author: Mat Buckland 2002 (fup#ai-junkie.com)
//
//------------------------------------------------------------------------
#include <string>
#include "messaging/Telegram.h"
class BaseGameEntity
{
private:
//every entity must have a unique identifying number
int m_ID;
static int m_iNextValidID;
void SetID(int val);
public:
BaseGameEntity(int id)
{
SetID(id);
}
virtual ~BaseGameEntity(){}
//all entities must implement an update function
virtual void Update()=0;
//all entities can communicate using messages. They are sent
//using the MessageDispatcher singleton class
virtual bool HandleMessage(const Telegram& msg)=0;
int ID()const{return m_ID;}
};
#endif
/////////////// here begins the cpp definition
#include "BaseGameEntity.h"
#include <cassert>
int BaseGameEntity::m_iNextValidID = 0;
void BaseGameEntity::SetID(int val)
{
//make sure the val is equal to or greater than the next available ID
assert ( (val >= m_iNextValidID) && "<BaseGameEntity::SetID>: invalid ID");
m_ID = val;
m_iNextValidID = m_ID + 1;
}
What Does assert statement check for in this case? And why the use of ":" after SetID in assert statement? I know the use of : to initialise elements via a constructor? But this usage is new to me.
This is a common trick when using assert macro from <cassert>. The macro fails if its argument evaluates to false, then the program exits without any readable diagnostic message (usually just a line number, file and stringified condition of the assert()).
That is, to improve the diagnostic message, one can hack the boolean expression by adding a string literal that will be printed out together with the condition:
assert((val >= m_iNextValidID) && "<BaseGameEntity::SetID>: invalid ID");
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The string literal always evaluates to boolean true (because it is a pointer), hence, it makes no impact to the condition itself. However, when the first operand of && condition fails, then the entire condtion is not satisfied (due to its logic) and assert ends the program, printing out:
Assertion failed: (val >= m_iNextValidID) && "<BaseGameEntity::SetID>: invalid ID"
Then, seeing this message, one can know that the provided ID for SetID method was not valid.
Related
I am trying to send a vector of "struct" per message, but when defining the message field the following error is generated:
Entering directory '/home/veins/workspace.omnetpp/veins/src'
veins/modules/application/clustertraci/ClusterTraCI11p.cc
veins/modules/application/clustertraci/ClusterTraCI11p.cc:160:40: error: no viable conversion from 'vector' to 'const vector'
frameOfUpdate->setUpdateTable(updateTable);
I read chapter 6 of the OMnet ++ manual, but I don't understand how to solve this problem.
Implementation with error
Message Code (MyMessage.msg):
cplusplus {{
#include "veins/base/utils/Coord.h"
#include "veins/modules/messages/BaseFrame1609_4_m.h"
#include "veins/base/utils/SimpleAddress.h"
#include <iostream>
#include <vector>
struct updateTableStruct {
int car;
char update;
};
typedef std::vector<updateTableStruct> UpdateTable;
}}
namespace veins;
class BaseFrame1609_4;
class noncobject Coord;
class noncobject UpdateTable;
class LAddress::L2Type extends void;
packet ClusterMessageUpdate extends BaseFrame1609_4 {
LAddress::L2Type senderAddress = -1;
int serial = 0;
UpdateTable updateTable;
MyApp.cc:
void ClusterTraCI11p::handleSelfMsg(cMessage* msg) {
if (ClusterMessage* frame = dynamic_cast<ClusterMessage*>(msg)) {
ClusterMessageUpdate* frameOfUpdate = new ClusterMessageUpdate;
populateWSM(frameOfUpdate, CH2);
frameOfUpdate->setSenderAddress(myId);
frameOfUpdate->setUpdateTable(updateTable);
sendDelayedDown(frameOfUpdate, uniform(0.1, 0.02));
}
else {
DemoBaseApplLayer::handleSelfMsg(msg);
}
}
Part of code for analysis in MyApp.h:
struct updateTableStruct {
int car;
char update;
};
typedef std::vector<updateTableStruct> UpdateTable;
UpdateTable updateTable;
You experience a type mismatch: In MyApp.h you define the type UpdateTable, and you do so in MyMessage.h. While these both types have the same content and appear to have the same name, I assume this is not actually the case: one type is UpdateTable (defined at global scope in the file generated based on your message) and the other is MyApp::UpdateTable (defined in your application, assuming you are omitting the class definition in the code you show).
Therefore, the types are different, and they cannot be converted into each other implicitly. In this case this might appear a bit counter-intuitive, as they have exactly the same definition, but they do not have the same name. In the following example the reasoning is shown: Two different types that share the same definition should not necessarily be implicitly convertible into each other:
struct Coordinate {
int x;
int y;
};
struct Money {
int dollars;
int cents;
};
void test() {
Coordinate c;
Money m = c;
}
Gives the following error message:
test.cc:13:8: error: no viable conversion from 'Coordinate' to 'Money'
Money m = c;
^ ~
test.cc:6:8: note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'Coordinate' to 'const Money &' for 1st argument
struct Money {
^
test.cc:6:8: note: candidate constructor (the implicit move constructor) not viable: no known conversion from 'Coordinate' to 'Money &&' for 1st argument
struct Money {
^
1 error generated.
Edit:
The solution to your specific problem is to remove one of the definitions and include the remaining definition when using it, so you can either remove the UpdateTable definition from the message and include the App header instead, or remove the UpdateTable definition from the App and include the message instead.
I have a simple struct, that has all constructors defined.
It has an int variable, each constructor and assign operator prints address of *this, current value of int and a new value of int.
Move and copy assign operators and constructors also print adress of passed value.
#include <iostream>
struct X
{
int val;
void out(const std::string& s, int nv, const X* from = nullptr)
{
std::cout<<this<<"->"<<s<<": "<<val<<" ("<<nv<<")";
if (from)
std::cout<<", from: ["<<from<<"]";
std::cout<<"\n";
}
X(){out("simple ctor X()",0); val = 0;}
X(int v){out("int ctor X(int)", v);val = v; }
X(const X& x){out("copy ctor X(X&)", x.val, &x);val = x.val; };
X&operator = (const X& x){out("copy X::operator=()", x.val, &x); val = x.val; return *this;}
~X(){out("dtor ~X", 0);}
X&operator = (X&& x){out("move X::operator(&&)", x.val, &x); val = x.val; return *this;}
X(X&& x){out("move ctor X(&&x)", x.val, &x);val = x.val;}
};
X copy(X a){return a;}
int main(int argc, const char * argv[]) {
X loc{4};
X loc2;
std::cout<<"before copy\n";
loc2 = copy(loc);
std::cout<<"copy finish\n";
}
output:
0xffdf7278->int ctor X(int): 134523184 (4)
0xffdf727c->simple ctor X(): 134514433 (0)
before copy
0xffdf7280->copy ctor X(X&): 1433459488 (4), from: [0xffdf7278]
0xffdf7284->move ctor X(&&x): 1433437824 (4), from: [0xffdf7280]
0xffdf727c->move X::operator(&&): 0 (4), from: [0xffdf7284]
0xffdf7284->dtor ~X: 4 (0)
0xffdf7280->dtor ~X: 4 (0)
copy finish
0xffdf727c->dtor ~X: 4 (0)
0xffdf7278->dtor ~X: 4 (0)
What's the purpose of creating an additional object with (in this example) address 0xffdf7284?
If you look at the copy elision rules from cppreference.com, you can notice that there are two case where the compilers are required to omit the copy- and move- constructors of class objects even if copy/move constructor and the destructor have observable side-effects (which yours do, due to the printouts). The first is clearly irrelevant to this case. The second is
In a function call, if the operand of a return statement is a prvalue and the return type of the function is the same as the type of that prvalue.
With the example given of:
T f() { return T{}; }
T x = f();
This seems more relevant, however, note that in your case, the operand of the return statement is not a prvalue. So in this case, no mandatory elision applies.
The set of steps, when callingloc2 = copy(loc);, is as follows:
a is copy-constructed from loc.
The return value of the function is move-constructed from a.
loc2 is move-assigned from the return value.
Logically, a person could look at the code and deduce that fewer operations need to be done (in particular, when looking at copy, it's obvious that, logically, an assignment from loc to loc2 is enough), but the compiler doesn't know that the purpose of your code isn't to generate the side effects (the printouts), and it is not breaking any rules here.
I'm trying to create sub containers of a container through container<\T>(InputIt First, InputIt Last). For example, I have a string s1="AreYouOK".
The expected outputs are
A
Ar
Are
AreY
AreYo
AreYou
AreYouO
Here is my code:
#include <vector>
#include <string>
#include <iostream>
using std::vector;
using std::string;
using std::cout;
using std::cin;
using std::endl;
int main()
{
string s1 = "AreYouOK";
vector<string> v;
for (string::const_iterator iter = s1.begin();
iter != s1.end()-1; ++iter)
{
string s(s1.begin(),iter); // no matching container
s += *iter;
v.push_back(s);
}
for (vector<string>::const_iterator iter = v.begin();
iter != v.end(); ++iter)
{
cout << *iter <<endl;
}
return 0;
}
I expect the commented line
string s(s1.begin(),iter);
to create a substring s of string s1 in range [s1.begin(), iter), since iter is an iterator of s1. However, I was told that there is no matching constructor for initialization.
error: no matching constructor for initialization of 'string'
(aka 'basic_string<char, char_traits<char>, allocator<char> >')
string s(s1.begin(),iter);
^ ~~~~~~~~~~~~~~~
While
string s(s1.begin(),s1.begin+3);
did manage to create a substring.
Why
string s(s1.begin(),iter);
did not work?
Many thanks!
If you look here, for example, you can see that a full error message contains
prog.cpp:19:33: error: no matching function for call to 'std::basic_string<char>::basic_string(std::basic_string<char>::iterator, std::basic_string<char>::const_iterator&)'
which says that it thinks your calling a constructor that takes an iterator and (reference to) const_iterator. There is no such constructor. Since s1 is a non-const object, s1.begin() returns a regular iterator.
There are many ways around this. One of them is to change your loop to
string::const_iterator b = s1.begin();
for (string::const_iterator iter = b;
iter != s1.end()-1; ++iter)
{
string s(b,iter);
...
Here you indeed use two const iterators (see here your expected output).
Edit
Two excellent (and superior) alternatives are:
Use cbegin if you're C++11 enabled (#rici)
Use accumulate, once you get to that algorithm (#PaulMcKenzie)
Im new to c++ and right now going through a course.
Im coding a bulls and cows guess my word game.
I finished the code, but it didnt work the way i wanted.
It fails when i try to pass variables between two functions.
thats the code:
#include <iostream>
#include <string>
using namespace std;
void PrintIntro(); <-- the function that passes the variable
void PlayGame(); <-- the function trying to get the vriable
string PlayersGuess();
int main()
{
// Printing the Intro and Instrations of the game
PrintIntro();
// Function to play our game
PlayGame();
return 0; // exits the application
}
void PrintIntro()
{
// introduce the game
constexpr int WORD_LENGTH = 5;
cout << "Welcome to Bulls and Cows" << endl;
cout << "Can you guess the " << WORD_LENGTH << " letter word I'm thinking of?" << endl;
cout << endl;
PlayGame(WORD_LENGTH); <-- Taking the variable
return;
}
string PlayersGuess()
{
// get a guess from the player
cout << "Enter your guess: ";
string Guess = "";
getline(cin, Guess);
cout << endl;
return Guess;
}
void PlayGame(const int &passed) <-- passing through here
{
// Game Intro
for (int i = 0; i < passed; i++) <-- to here
{
// Players Guess
string Guess = PlayersGuess();
cout << "Your guess is: " << PlayersGuess() << endl;
cout << endl;
}
}
The result is a fail and it says "Function does not take 1 argument"
What is the right way to pass it?
Change the declaration :
void PlayGame()
To:
void PlayGame(const int &passed)
The declaration void PlayGame(); in the beginning does not accept parameter. Change the declaration to accept parameter of the required type. Declaration and definition must match. Hope this helps.
If you want a function to take an argument, you have to tell the compiler it takes an argument.
The function prototype declaration
void PlayGame();
tells the compiler that the PlayGame function takes no arguments, and return no value. If you then try to call it using an argument that doesn't match the declaration and you will get an error.
On the other hand, if you declare it like your definition:
void PlayGame(const int &passed);
then you tell the compiler that the function must take an argument (a reference to a constant int), and you can not call the function without argument.
If you want different behavior depending on the argument (or lack thereof) passed, then you have two solutions: Function overloading, or default arguments.
For example, you can have two different functions with the same name, but different signature (basically different arguments), so you can have e.g.
void PlayGame() { ... }
void PlayGame(int passed) { ... }
Then (with the right forward declarations) you can call it with either no arguments in which case the first function will be called, or with an integer value in which case the second function will be called.
Using default arguments you can do something like
void PlayGame(int passed = 0) { ... }
Then if you call the function with an argument that argument will be passed, if you pass it without any argument the default value (0 in my example) will be used.
Also note that I removed the constant reference part, that's not really needed for simple int values.
All of this should be clearly explained in any good book.
Signatures of functions' declaration and definition must match each other. You need to declare functions like this:
void PlayGame(const int &passed);
In your code you have two different functions with name PlayGame. In the moment when PlayGame() is called with a parameter a compiler hasn't met the appropriate function yet so it gives the error.
I realize this has been asked before more than once on SO but I couldn't find a question explicitly looking for a current solution to this issue with C++11, so here we go again..
Can we conveniently get the string value of an enum with C++11?
I.e. is there (now) any built-in functionality in C++11 that allows us to get a string representation of enum types as in
typedef enum {Linux, Apple, Windows} OS_type;
OS_type myOS = Linux;
cout << myOS
that would print Linux on the console?
The longstanding and unnecessary lack of a generic enum-to-string feature in C++ (and C) is a painful one. C++11 didn't address this, and as far as I know neither will C++14.
Personally I'd solve this problem using code generation. The C preprocessor is one way--you can see some other answers linked in the comments here for that. But really I prefer to just write my own code generation specifically for enums. It can then easily generate to_string (char*), from_string, ostream operator<<, istream operator<<, is_valid, and more methods as needed. This approach can be very flexible and powerful, yet it enforces absolute consistency across many enums in a project, and it incurs no runtime cost.
Do it using Python's excellent "mako" package, or in Lua if you're into lightweight, or the CPP if you're against dependencies, or CMake's own facilities for generating code. Lots of ways, but it all comes down to the same thing: you need to generate the code yourself--C++ won't do this for you (unfortunately).
In my opinion, the most maintainable approach is to write a helper function:
const char* get_name(OS_type os) {
switch (os) {
case Linux: return "Linux";
case Apple: return "Apple";
case Windows: return "Windows";
}
}
It is a good idea not to implement the "default" case, since doing so will ensure that you get a compiler warning if you forget to implement a case (with the right compiler and compiler settings).
I like a hack using the C preprocessor, which I first saw here:
http://blogs.msdn.com/b/vcblog/archive/2008/04/30/enums-macros-unicode-and-token-pasting.aspx .
It uses the token-pasting operator # .
// This code defines the enumerated values:
#define MY_ENUM(x) x,
enum Fruit_Type {
MY_ENUM(Banana)
MY_ENUM(Apple)
MY_ENUM(Orange)
};
#undef MY_ENUM
// and this code defines an array of string literals for them:
#define MY_ENUM(x) #x,
const char* const fruit_name[] = {
MY_ENUM(Banana)
MY_ENUM(Apple)
MY_ENUM(Orange)
};
#undef MY_ENUM
// Finally, here is some client code:
std::cout << fruit_name[Banana] << " is enum #" << Banana << "\n";
// In practice, those three "MY_ENUM" macro calls will be inside an #include file.
Frankly, it's ugly and. but you end up typing your enums exactly ONCE in an include file, which is more maintainable.
BTW, on that MSDN blog link (see above) a user made a comment with a trick that makes the whole thing much prettier, and avoids #includes:
#define Fruits(FOO) \
FOO(Apple) \
FOO(Banana) \
FOO(Orange)
#define DO_DESCRIPTION(e) #e,
#define DO_ENUM(e) e,
char* FruitDescription[] = {
Fruits(DO_DESCRIPTION)
};
enum Fruit_Type {
Fruits(DO_ENUM)
};
// Client code:
std::cout << FruitDescription[Banana] << " is enum #" << Banana << "\n";
(I just noticed that 0x17de's answer also uses the token-pasting operator)
Here is a simple example using namespaces and structs.
A class is created for each enum item. In this example i chose int as the type for the id.
#include <iostream>
using namespace std;
#define ENUMITEM(Id, Name) \
struct Name {\
static constexpr const int id = Id;\
static constexpr const char* name = #Name;\
};
namespace Food {
ENUMITEM(1, Banana)
ENUMITEM(2, Apple)
ENUMITEM(3, Orange)
}
int main() {
cout << Food::Orange::id << ":" << Food::Orange::name << endl;
return 0;
}
Output:
3:Orange
== Update ==
Using:
#define STARTENUM() constexpr const int enumStart = __LINE__;
#define ENUMITEM(Name) \
struct Name {\
static constexpr const int id = __LINE__ - enumStart - 1;\
static constexpr const char* name = #Name;\
};
and using it once before the first usage of ENUMITEM the ids would not be needed anymore.
namespace Food {
STARTENUM()
ENUMITEM(Banana)
ENUMITEM(Apple)
ENUMITEM(Orange)
}
The variable enumStart is only accessible through the namespace - so still multiple enums can be used.
You can use macro to solve this problem:
#define MAKE_ENUM(name, ...) enum class name { __VA_ARGS__}; \
static std::vector<std::string> Enum_##name##_init(){\
const std::string content = #__VA_ARGS__; \
std::vector<std::string> str;\
size_t len = content.length();\
std::ostringstream temp;\
for(size_t i = 0; i < len; i ++) {\
if(isspace(content[i])) continue;\
else if(content[i] == ',') {\
str.push_back(temp.str());\
temp.str(std::string());}\
else temp<< content[i];}\
str.push_back(temp.str());\
return str;}\
static const std::vector<std::string> Enum_##name##_str_vec = Enum_##name##_init();\
static std::string to_string(name val){\
return Enum_##name##_str_vec[static_cast<size_t>(val)];\
}\
static std::string print_all_##name##_enum(){\
int count = 0;\
std::string ans;\
for(auto& item:Enum_##name##_str_vec)\
ans += std::to_string(count++) + ':' + item + '\n';\
return ans;\
}
As the static variable can only be initialized once, so the Enum_##name##_str_vec will use the Enum_##name##_init() function to initialize itself at first.
The sample code is as below:
MAKE_ENUM(Analysis_Time_Type,
UNKNOWN,
REAL_TIME,
CLOSSING_TIME
);
Then you can use below sentence to print an enum value:
to_string(Analysis_Time_Type::UNKNOWN)
And use below sentence to print all enum as string:
print_all_Analysis_Time_Type_enum()
As mentioned, there is no standard way to do this. But with a little preprocessor magic (similar to AlejoHausner's second contribution) and some template magic, it can be fairly elegant.
Include this code once:
#include <string>
#include <algorithm>
#define ENUM_VALS( name ) name,
#define ENUM_STRINGS( name ) # name,
/** Template function to return the enum value for a given string
* Note: assumes enums are all upper or all lowercase,
* that they are contiguous/default-ordered,
* and that the first value is the default
* #tparam ENUM type of the enum to retrieve
* #tparam ENUMSIZE number of elements in the enum (implicit; need not be passed in)
* #param valStr string version of enum value to convert; may be any capitalization (capitalization may be modified)
* #param enumStrs array of strings corresponding to enum values, assumed to all be in lower/upper case depending upon
* enumsUpper
* #param enumsUpper true if the enum values are in all uppercase, false if in all lowercase (mixed case not supported)
* #return enum value corresponding to valStr, or the first enum value if not found
*/
template <typename ENUM, size_t ENUMSIZE>
static inline ENUM fromString(std::string &valStr, const char *(&enumStrs)[ENUMSIZE], bool enumsUpper = true) {
ENUM e = static_cast< ENUM >(0); // by default, first value
// convert valStr to lower/upper-case
std::transform(valStr.begin(), valStr.end(), valStr.begin(), enumsUpper ? ::toupper : ::tolower);
for (size_t i = 0; i< ENUMSIZE; i++) {
if (valStr == std::string(enumStrs[i])) {
e = static_cast< ENUM >(i);
break;
}
}
return e;
}
Then define each enum like so:
//! Define ColorType enum with array for converting to/from strings
#define ColorTypes(ENUM) \
ENUM(BLACK) \
ENUM(RED) \
ENUM(GREEN) \
ENUM(BLUE)
enum ColorType {
ColorTypes(ENUM_VALS)
};
static const char* colorTypeNames[] = {
ColorTypes(ENUM_STRINGS)
};
You only have to enumerate the enum values once and the code to define it is fairly compact and intuitive.
Values will necessarily be numbered in the default way (ie, 0,1,2,...). The code of fromString() assumes that enum values are in either all uppercase or all lowercase (for converting from strings) that the default value is first, but you can of course change how these things are handled.
Here is how you get the string value:
ColorType c = ColorType::BLUE;
std::cout << colorTypeNames[c]; // BLUE
Here is how you set the enum from a string value:
ColorType c2 = fromString<ColorType>("Green", colorTypeNames); // == ColorType::GREEN