I'm writing a simple class for atoms objects. Here's what I've written so far:
#include <random>
class Atom {
int mSpin;
public:
Atom();
Atom(int);
Atom(const Atom&);
~Atom() {}
Atom& operator= (const Atom &atom);
};
And the .cpp file:
include "Atom.h"
Atom::Atom() {
}
Atom::Atom(int spin) : mSpin(spin) {}
Atom::Atom(const Atom& copy) : mSpin(copy.mSpin) {}
/* OPERATORS */
Atom& Atom::operator= (const Atom ©) {
mSpin = copy.mSpin;
return *this;
}
I want to make the default constructor such that when I'm creating an object, mSpin will be randomly set as 1 or -1. I understand how to do it with rand() but rand() is not very good and I'd like to use . I'm kind of confused by the use of , even after reading the documentation and other answers on here.
Usually I'd do something like this:
#include <random>
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(0,1);
int random_number = dis(gen);
but I'm not sure how to use it inside a class. I tried placing it inside the default constructor but I think it's wrong because it would seed each time I create an atom?
Hope the question is clear.
You should make the random device and generator static members of the Atom class. This way, like global variables, they are initialized only once for the duration of your program.
class Atom {
// declaration
static std::random_device rd;
static std::mt13397 gen;
...
};
// definition - this must be in Atom.cpp
std::random_device Atom::rd;
std::mt13397 Atom::gen(Atom::rd());
You can delegate to a function in the cpp file:
namespace {
random_device rd;
mt19937 gen(rd());
uniform_int_distribution<> dis(0,1);
}
int spin() {
return dis(gen) == 0 ? -1 : 1;
}
Delete your implementation of the default CTOR.
And to follow the rule 'initialise all variables' change Atom.hpp:
int spin(); // Return -1 or 1, randomly
class Atom {
int mSpin = spin();
public:
Atom() = default;
...
};
Then, in your cpp file, delete your Atom default CTOR implementation and move 'spin' function definition out of the anonymous namespace.
Related
I have read here that "C/C++ constants are installed as global Tcl variables containing the appropriate value", which applies to enum as well. I am trying to build a Tcl wrapper using swig for an enum class (called "Statement") that will result into the corresponding Tcl variables to be stored as string objects. The C++ code provides some ostream conversion facilities that I thought I could use to perform the conversion, but I cannot find a recipe that will work. I have tried the following:
//%typemap(argout) Statement *out {
// ostringstream oss;
// oss << $1;
// $result = Tcl_NewStringObj(oss.str()->c_str(), oss.str().size());
//}
//%typemap(constcode) Statement {
// ostringstream oss;
// oss << $1;
// $result = Tcl_NewStringObj(oss.str()->c_str(), oss.str().size());
//}
//%typemap(out) Statement {
// ostringstream oss;
// oss << $1;
// $result = Tcl_NewStringObj(oss.str()->c_str(), oss.str().size());
//}
Another (maybe related issue) is that no Tcl variables are created at all from the enums in my wrapper. I read from this follow up link that when you use static linking, the Tcl variables used to store constants will be put in the ::swig namespace. But this is not my problem here: I do not have a ::swig namespace, and info vars does not list any variables in the top namespace either.
I have found the answer for the second issue. My wrapper SWIG code uses the %init directive which uses some magic to make use of the readline library. It was evaluating a Tcl script that starts the readline command processing loop before the rest of the application initialization got a chance to complete. The constant initialization code was generated after the block of code provided to the %init SWIG block, so it never got executed. By moving the SWIG declaration of the enum above the %init section, the relative order of inserted constant initialization code and %init segment was changed, and the issue was solved.
Bottom-line: the relative order of declaration and %init segment in your SWIG wrapper code matters.
I was able to resolve this using a typemap of the form:
%typemap(out) enum NS::Statement {
ostringstream oss;
oss << "NS_Statement(" << $1 << ")";
Tcl_SetObjResult(interp,Tcl_NewStringObj(oss.str().c_str(), oss.str().size()));
}
The reason it was not working previously is that the enum is defined within a namespace statement. Even though I had 'using namespace NS;' statement before the typemap declaration, it was not being applied until I provided the full namespace qualifier of the enum. Also, both typemap statements had to be provided before the wrapper code declaring the enum constants.
As you can see, the variable name that is returned is a Tcl array variable name. In order for things to be consistent, the global variables set by the generated code that contain the actual values of the enum need also be changed. I was able to achieve that using another typemap like so:
%typemap(constcode,noblock=1) int {
%set_constant("NS_Statement($symname)", SWIG_From_long(static_cast< int >($1)));
}
In the case where you need to wrap multiple enum type, just insert a similar set of typemaps for each enum before its SWIG declaration, matching the Tcl array name part with the enum type being mapped. In case where there are non-enum constants to be declared in your SWIG code, or other enum types that you do not want to wrap in that way, add a last typemap(constcode) to reset to default behavior before you add the SWIG code declaring these other constants.
I have created a small example that illustrates that approach:
// file example.h
enum TOPETYPE {BI, DUL, BUC};
class MyClass {
public:
enum ETYPE {ONE,TWO, THREE};
static void Foo(ETYPE);
static ETYPE Bar(int);
};
namespace NS {
enum LIBENUM {LIB1, LIB2, LIB3};
}
extern const char * ETYPE2Str(MyClass::ETYPE);
extern const char * TOPETYPE2Str(TOPETYPE);
extern const char * LIBENUM2Str(NS::LIBENUM);
/* File : example.i */
%module example
%{
#include "example.h"
#include <sstream>
using namespace std;
%}
#define XX 0
%typemap(out) enum TOPETYPE {
#include <iostream>
std::ostringstream oss;
oss << "TOPETYPE(" << TOPETYPE2Str($1) << ")";
Tcl_SetObjResult(interp,Tcl_NewStringObj(oss.str().c_str(), -1));
}
%typemap(constcode,noblock=1) int {
%set_constant("TOPETYPE($symname)", SWIG_From_long(static_cast< int >($1)));
}
enum TOPETYPE {BI, DUL, BUC};
%typemap(out) enum MyClass::ETYPE {
#include <iostream>
std::ostringstream oss;
oss << "MyClass_ETYPE(MyClass_" << ETYPE2Str($1) << ")";
Tcl_SetObjResult(interp,Tcl_NewStringObj(oss.str().c_str(), -1));
}
%typemap(constcode,noblock=1) int {
%set_constant("MyClass_ETYPE($symname)", SWIG_From_long(static_cast< int >($1)));
}
class MyClass {
public:
enum ETYPE {ONE,TWO, THREE};
static void Foo(ETYPE);
static ETYPE Bar(int);
};
%typemap(out) enum NS::LIBENUM {
#include <iostream>
std::ostringstream oss;
oss << "NS_LIBENUM(" << LIBENUM2Str($1) << ")";
Tcl_SetObjResult(interp,Tcl_NewStringObj(oss.str().c_str(), -1));
}
%typemap(constcode,noblock=1) int {
%set_constant("NS_LIBENUM($symname)", SWIG_From_long(static_cast< int >($1)));
}
namespace NS {
enum LIBENUM {LIB1, LIB2, LIB3};
}
// file example.cpp
#include "example.h"
#include <iostream>
using namespace std;
void MyClass::Foo(MyClass::ETYPE typ)
{
cout << "Enum value = " << typ << endl;
}
MyClass::ETYPE MyClass::Bar(int val)
{
switch (static_cast<MyClass::ETYPE>(val)) {
case MyClass::ETYPE::ONE: {return MyClass::ETYPE::ONE;}
case MyClass::ETYPE::TWO: {return MyClass::ETYPE::TWO;}
case MyClass::ETYPE::THREE: {return MyClass::ETYPE::THREE;}
default: {return MyClass::ETYPE::THREE;}
}
}
const char * ETYPE2Str(MyClass::ETYPE val) {
switch (val) {
case MyClass::ETYPE::ONE: {return "ONE";}
case MyClass::ETYPE::TWO: {return "TWO";}
case MyClass::ETYPE::THREE: {return "THREE";}
default: {return "unknown";}
}
}
const char * TOPETYPE2Str(TOPETYPE val) {
switch (val) {
case TOPETYPE::BI: {return "BI";}
case TOPETYPE::DUL: {return "DUL";}
case TOPETYPE::BUC: {return "BUC";}
default: {return "unknown";}
}
}
const char * LIBENUM2Str(NS::LIBENUM val) {
switch (val) {
case NS::LIB1: {return "LIB1";}
case NS::LIB2: {return "LIB2";}
case NS::LIB3: {return "LIB3";}
default: {return "unknown";}
}
}
You can try this out with:
swig -c++ -tcl8 example.i
g++ -c -fpic example_wrap.cxx example.cpp -I/usr/local/include
g++ -shared example.o example_wrap.o -o example.so
And then, inside tclsh:
% load example4.so
% info vars
XX tcl_rcFileName tcl_version argv0 argv tcl_interactive auto_path errorCode NS_LIBENUM errorInfo auto_execs auto_index env tcl_pkgPath MyClass_ETYPE TOPETYPE tcl_patchLevel swig_runtime_data_type_pointer4 argc tcl_library tcl_platform
% info commands
MyClass_Bar tell socket subst open eof pwd glob list pid exec auto_load_index time unknown eval lassign lrange fblocked lsearch auto_import gets case lappend proc break variable llength auto_execok return linsert error catch clock info split array if fconfigure concat join lreplace source fcopy global switch auto_qualify update close cd for auto_load file append lreverse format unload read package set binary namespace scan delete_MyClass apply trace seek while chan flush after vwait dict continue uplevel foreach lset rename fileevent regexp new_MyClass lrepeat upvar encoding expr unset load regsub history interp exit MyClass puts incr lindex lsort tclLog MyClass_Foo string
% array names NS_LIBENUM
LIB1 LIB2 LIB3
% array names MyClass_ETYPE
MyClass_TWO MyClass_ONE MyClass_THREE
% array names TOPETYPE
DUL BUC BI
% puts $XX
0
% MyClass_Bar $MyClass_ETYPE(MyClass_ONE)
MyClass_ETYPE(MyClass_ONE)
% MyClass_Foo $MyClass_ETYPE(MyClass_ONE)
Enum value = 0
% exit
I am developing a cache and I need to know when an object expired.
Is possible run a function when the reference counter of a shared_ptr decrease?
std::shared_ptr< MyClass > p1 = std::make_shared( MyClass() );
std::shared_ptr< MyClass > p2 = p1; // p1.use_count() = 2
p2.reset(); // [ run function ] p1.use_count() = 1
You can't have a function called every time the reference count decreases, but you can have one called when it hits zero. You do this by passing a "custom deleter" to the shared_ptr constructor (you can't use the make_shared utility for this); the deleter is a callable object which is responsible for being passed, and deleting, the shared object.
Example:
#include <iostream>
#include <memory>
using namespace std;
void deleteInt(int* i)
{
std::cout << "Deleting " << *i << std::endl;
delete i;
}
int main() {
std::shared_ptr<int> ptr(new int(3), &deleteInt); // refcount now 1
auto ptr2 = ptr; // refcount now 2
ptr.reset(); // refcount now 1
ptr2.reset(); // refcount now 0, deleter called
return 0;
}
You can specify a deleter functor when creating the shared_ptr. The following article show an example use of a deleter:
http://en.cppreference.com/w/cpp/memory/shared_ptr/shared_ptr
Not using a vanilla std::shared_ptr, but if you only require customized behaviour when calling reset() (with no arguments), you can easily create a custom adapter:
template <typename T>
struct my_ptr : public std::shared_ptr<T> {
using std::shared_ptr<T>::shared_ptr;
void reset() {
std::shared_ptr<T>::reset(); // Release the managed object.
/* Run custom function */
}
};
And use it like this:
my_ptr<int> p = std::make_shared<int>(5);
std::cout << *p << std::endl; // Works as usual.
p.reset(); // Customized behaviour.
Edit
This answer is meant to suggest a solution to an issue that I didn't think the other answers did address, that is: executing custom behaviour every time when the refcount is decreased by use of reset().
If the issue is simply to make a call upon object release, then use a custom deleter functor as suggested in the answers by #Sneftel and #fjardon.
I would like to know if there is a way to store functional objects (functions, callbacks, ...) with different signatures in a standard container (std::map) with modern C++ only. The library that manages the container does not know which signatures will be used by its "clients".
My need is the same as exposed here : How to store functional objects with different signatures in a container?, and this solution https://stackoverflow.com/a/8304873/4042960 is about perfect for me: I would just like to do the same thing without boost. As far as I know, there is no std::any. The best solution for me would be to store std::function without specialized them, but I do not know how to do it, if it is possible.
Edit:
With the answers you give to me I wrote this example :
#include <map>
#include <memory>
#include <functional>
#include <string>
#include <iostream>
#include <stdexcept>
class FunctionMap
{
struct Base {
virtual ~Base() {}
};
template<class R, class... Args>
struct Func : Base
{
std::function<R(Args...)> f;
};
std::map<std::string, std::shared_ptr<Base> > _map;
public:
template<class R, class... Args>
void store(const std::string &key, const std::function<R(Args...)> &f) {
auto pfunc = std::make_shared<Func<R, Args...> >();
pfunc->f = f;
_map.insert(std::make_pair(key, pfunc));
}
template<class R, class... Args>
std::function<R(Args...)> get(const std::string &key) {
auto pfunc = std::dynamic_pointer_cast<Func<R, Args...> >(_map[key]);
if (pfunc)
return pfunc->f;
else
throw std::runtime_error("Bad type for function's parameters");
}
};
// test
int plus(int a, int b) { return a+b; }
double multiplies(double x, double y) { return x*y; }
int main()
{
FunctionMap fm;
fm.store("plus", std::function<int(int, int)>(&plus));
fm.store("multiplies", std::function<double(double, double)>(&multiplies));
// fm.store("square", std::bind(&multiplies, std::placeholders::_1, std::placeholders::_1));
std::cout << "5 + 3 = " << fm.get<int, int, int>("plus")(5, 3) << std::endl;
std::cout << "5 * 3 = " << fm.get<double, double, double>("multiplies")(5.0, 3.0) << std::endl;
return 0;
}
This works well, but I would like to improve it a bit:
1) I would like to be able to use std::bind : fm.store("square", std::bind(&multiplies, std::placeholders::_1, std::placeholders::_1)); but currently that does not compile ;
2) I would like to use fm.get<int (int, int)>("plus") instead of fm.get<int, int, int>("plus") but I do not know how to do it.
Many thanks for your help !
You can write your own any. Without all the compiler workarounds and stuff, boost::any can be written in about 30 lines of code.
Function objects are in no way different from any other kind of objects, so anything applicable to objects in general is applicable to function objects.
So you want to store different kinds of (function) objects in a map. This is normally done by storing (smart) pointers to a base class, where each derived class holds its own kind of objects you want to store.
struct Base {
virtual ~Base(){}
};
template <typename A>
struct Object : Base {
A value;
};
That's your basic caveman's boost::any. Your clients do something like this:
Base* b = mymap["foo"];
dynamic_cast<Object<void(*)(int)>*>(b)->val(123);
But with appropriate checks of course.
This is just theoretical question. When i execute this code:
#include <functional>
#include <cstdio>
struct A {
int value = 100;
A() {
printf("A\n");
}
A(const A& a) {
printf("copy A\n");
}
~A() {
printf("~A\n");
}
};
void function(std::function<int()> lambda) {
printf("%d\n", lambda());
}
int main()
{
A a;
auto lambda = [a]() -> int {
return a.value;
};
function(lambda);
return 0;
}
Output is this:
A
copy A
copy A
copy A
100
~A
~A
~A
~A
And my question is why struct A is copied 3 times, not 2?
One copy takes lambda capture, second takes passing argument to function and third takes what?
You will see the same number of copy operations, if you change your code as follows:
int main()
{
A a;
auto&& lambda = [a]() -> int {
return a.value;
};
std::function<int()>{lambda};
}
The first copy/move construction occurs when creating the lambda. The second and third copy/move constructions happen during construction of the std::function. According to N3690, the used constructor of std::function looks as follows:
template <class F> function(F);
That means, the passed argument will be copied/moved once when passing the argument to the constructor. Within the constructor, it will be copied/moved another time for type erasure.
If the constructor would use references instead (e.g. with perfect forwarding), you would only see two copy/move constructions. However, I don't know why it wasn't used in this case.
template <typename Arg> function(Arg&&);
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