There are several good answers like this that offer a concise random-only application, but I'm having trouble expanding from that to a small part of a larger application.
Here's what I'm doing:
#include <random>
class RandomFP16
{
public:
static RandomFP16* GetInstance();
int GetRandom();
private:
static RandomFP16* singleton;
RandomFP16();
std::mt19937 mt;
std::uniform_int_distribution<int> dist;
};
RandomFP16* RandomFP16::GetInstance()
{
if(singleton == 0)
{
singleton = new RandomFP16();
}
return singleton;
}
RandomFP16::RandomFP16()
{
std::random_device rd;
//next two lines have errors
mt(rd());
dist(0x00000000, 0x00010000); //fixed-point 16.16
}
int RandomFP16::GetRandom()
{
return dist(mt);
}
So basically, I want one shared random generator that can be used anywhere anytime...at random. :-) Coming from embedded C and Windows C#, I see some strange syntax being used here, so I'm not sure how to structure things to get rid of these errors:
error: no match for call to '(std::mt19937 {aka std::mersenne_twister_engine<unsigned int, 32u, 624u, 397u, 31u, 2567483615u, 11u, 4294967295u, 7u, 2636928640u, 15u, 4022730752u, 18u, 1812433253u>}) (std::random_device::result_type)'
mt(rd());
^
.
error: no match for call to '(std::uniform_int_distribution<int>) (int, int)'
dist(0x00000000, 0x00010000);
^
Okay, I got it. Posting anyway to save someone some work.
#include <random>
class RandomFP16
{
public:
static RandomFP16* GetInstance();
int GetRandom();
private:
static RandomFP16* singleton;
RandomFP16(std::random_device::result_type seed);
std::mt19937 mt;
std::uniform_int_distribution<int> dist;
};
RandomFP16* RandomFP16::singleton = 0;
RandomFP16* RandomFP16::GetInstance()
{
if(singleton == 0)
{
std::random_device rd;
singleton = new RandomFP16(rd());
}
return singleton;
}
RandomFP16::RandomFP16(std::random_device::result_type seed)
: mt(seed), dist(0x00000000, 0x00010000) //fixed-point 16.16
{
}
int RandomFP16::GetRandom()
{
return dist(mt);
}
Turns out the class definition was right; the problems were all in the implentation:
The static variable needs to be declared again outside the class definition. (no idea why)
Local variables (not pointers) with constructors must be initialized like this.
That added an argument to this constructor, which then had to be fed from GetInstance()
Related
I'm trying to declare a friend function of a class with static members. I compiled my program in Visual Studio 2017 and faced this compile-time error:
unresolved external symbol "private: static struct Number * user::Link" (?Link#user##0PAUNumber##A)
Here's my code:
#include<iostream>
using namespace std;
typedef struct Number
{
int number;
struct Number *Link;
}
num_t;
class user
{
private:
static num_t *Link;
static int Length;
public:
static void Create()
{
cout << "You called a function." << endl;
Link->number = 1;
}
friend void Show_menu();
};
void Show_menu()
{
user::Create();
}
int user::Length = 1;
num_t user::*Link = nullptr;
int main()
{
return 0;
}
Generally, Is it possible to define a friend function of a class with static members in C++? If so, how do I fix the problem above?
I think you wanted num_t* user::Link = nullptr;.
The error has nothing to do with the declared friend.
In certain cases when programming with libraries written in C involving callbacks, I like to use Lambda expressions; however, if I need to alter the state of a class member variable I can't juts pass this into a stateless(function pointer) lambda. But I can assign this to a data in a context structure. What I find strange is being able to access that member variable even if it's private in the class.
Here's an example code I wrote to demonstrate.
#include <iostream>
using std::cout;
typedef struct extradatatype{
void* data;
}extradata;
extradata e = {0};
typedef void(*callback)(extradata* e);
void cb(callback c){
c(&e);
}
class Test{
private:
int x;
public:
Test(int x){
this->x = x;
}
void setcb(){
cb([](extradata* e){
Test* self = reinterpret_cast<Test*>(e->data);
self->x = 20;
});
}
int getx(){
return x;
}
};
int main(){
Test t(10);
e.data = &t;
t.setcb();
cout << t.getx();
return 0;
}
In the Lambda expression Test* self is assigned to e->data but I can access self->x as if it were a public member instead of private. So what I'm confused about is, is the lambda expression expression being executed within the stack/context of the setcb function or is it being executed elsewhere as its own function but C++ is doing some weird trick to allow private members to be accessed. Because I assume a stateless lambda is really no different than a non member static function which has no access to private members of a class.
Since your lambda function is defined within the class Test context, it will have access to class Test private member (regardless if it's this.x or self.x where self is of type Test). It is similar to this example:
class Example {
private:
int x;
public:
int f(Example e) {
return e.x;
}
};
where, since f is a member of Example, it can access e.x because e has type Example.
If you move your lambda function definition out of the class context you'll see the expected error message:
void outside(extradata* e);
class Test{
private:
int x;
public:
void setcb(){
cb(outside);
}
};
void outside(extradata* e) {
Test* self = reinterpret_cast<Test*>(e->data);
self->x = 20; // error here!
}
test.cpp:32:11: error: 'int Test::x' is private within this context
self->x = 20;
^
Historically, I've been using trait classes to hold information and apply that into a "generic" function that runs the same "algorithm." Only differed by the trait class. For example: https://onlinegdb.com/ryUo7WRmN
enum selector { SELECTOR1, SELECTOR2, SELECTOR3, };
// declaration
template < selector T> struct example_trait;
template<> struct example_trait<SELECTOR1> {
static constexpr size_t member_var = 3;
static size_t do_something() { return 0; }
};
template<> struct example_trait<SELECTOR2> {
static constexpr size_t member_var = 5;
static size_t do_something() { return 0; }
};
// pretend this is doing something useful but common
template < selector T, typename TT = example_trait<T> >
void function() {
std::cout << TT::member_var << std::endl;
std::cout << TT::do_something() << std::endl;
}
int main()
{
function<SELECTOR1>();
function<SELECTOR2>();
return 0;
}
I'm not sure how to create "generic" algorithms this when dealing with polymorphic classes.
For example: https://onlinegdb.com/S1hFLGC7V
Below I have created an inherited class hierarchy. In this example I have a base catch-all example that defaults all the parameters to something (0 in this case). And then each derived class sets overrides specific methods.
#include <iostream>
#include <memory>
#include <type_traits>
#include <assert.h>
using namespace std;
struct Base {
virtual int get_thing_one() {
return 0;
}
virtual int get_thing_two() {
return 0;
}
virtual int get_thing_three() {
return 0;
}
virtual int get_thing_four() {
return 0;
}
};
struct A : public Base {
virtual int get_thing_one() override {
return 1;
}
virtual int get_thing_three() override {
return 3;
}
};
struct B : public Base {
virtual int get_thing_one() override {
return 2;
}
virtual int get_thing_four() override{
return 4;
}
};
Here I created a simple factory, not elegant but for illustrative purposes
// example simple factory
std::shared_ptr<Base> get_class(const int input) {
switch(input)
{
case 0:
return std::shared_ptr<Base>(std::make_shared<A>());
break;
case 1:
return std::shared_ptr<Base>(std::make_shared<B>());
break;
default:
assert(false);
break;
}
}
So this is the class of interest. It is a class does "something" with the data from the classes above. The methods below are a simple addition example but imagine a more complicated algorithm that is very similar for every method.
// class that uses the shared_ptr
class setter {
private:
std::shared_ptr<Base> l_ptr;
public:
setter(const std::shared_ptr<Base>& input):l_ptr(input)
{}
int get_thing_a()
{
return l_ptr->get_thing_one() + l_ptr->get_thing_two();
}
int get_thing_b()
{
return l_ptr->get_thing_three() + l_ptr->get_thing_four();
}
};
int main()
{
constexpr int select = 0;
std::shared_ptr<Base> example = get_class(select);
setter l_setter(example);
std::cout << l_setter.get_thing_a() << std::endl;
std::cout << l_setter.get_thing_b() << std::endl;
return 0;
}
How can I make the "boilerplate" inside the setter class more generic? I can't use traits as I did in the example above because I can't tie static functions with an object. So is there a way to make the boilerplate example more common?
Somewhere along the lines of having a selector, say
enum thing_select { THINGA, THINGB, };
template < thing_select T >
struct thing_traits;
template <>
struct thing_traits<THINGA>
{
static int first_function() --> somehow tied to shared_ptr<Base> 'thing_one' method
static int second_function() --> somehow tied to shared_ptr<Base> 'thing_two' method
}
template <>
struct thing_traits<THINGB>
{
static int first_function() --> somehow tied to shared_ptr<Base> 'thing_three' method
static int second_function() --> somehow tied to shared_ptr<Base> 'thing_four' method
}
// generic function I'd like to create
template < thing_select T, typename TT = thing_traits<T> >
int perform_action(...)
{
return TT::first_function(..) + TT::second_function(..);
}
I ideally would like to modify the class above to something along the lines of
// Inside setter class further above
int get_thing_a()
{
return perform_action<THINGA>(...);
}
int get_thing_b()
{
return perform_action<THINGB>(...);
}
The answer is, maybe I can't, and I need to pass int the shared_ptr as a parameter and call the specific methods I need instead of trying to tie a shared_ptr method to a static function (in hindsight, that doesn't sound like a good idea...but I wanted to bounce my idea)
Whoever makes the actual call will need a reference of the object, one way or the other. Therefore, assuming you want perform_action to perform the actual call, you will have to pass the parameter.
Now, if you really want to store which function of Base to call as a static in thing_traits without passing a parameter, you can leverage pointer to member functions:
template <>
struct thing_traits<THINGA>
{
static constexpr int (Base::*first_function)() = &Base::get_thing_one;
...
}
template < thing_select T, typename TT = thing_traits<T>>
int perform_action(Base & b)
{
return (b.*TT::first_function)() + ...;
}
You can also play instead with returning a function object that does the call for you (and the inner function takes the parameter).
It all depends on who you need to make the call and what information/dependencies you assume you have available in each class/template.
Here is the specifics:
Consider a simple constructor in a class with two input arguments,
concreteclass(_1, _2).
I have a map for this instantiation, map <string, concreteclassType>.
Also, these classes work with different datatypes concreteclass<double>(_1,_2) is different from concreteclass<int>(_1,_2).
Now that my problem is described above here is what I try to do using boost::factory pattern, classes defined in a string map and datatypes defined in an enum.
First, there is a simple way to demonstrate how boost factory pattern can be used with constructor arguments, the following nicely code works:
// Factory which takes two arguments
struct base {
base(int alpha) : alpha(alpha) {}
virtual ~base() = default;
virtual void print() const = 0;
int alpha;
};
struct derived : public base {
derived(int alpha, int beta) : base(alpha), beta(beta) {}
void print() const override {
std::cout << alpha << " " << beta << std::endl;
}
int beta;
};
void TestBoostFactoryWithTwoArgs()
{
// Constructor factory with two input args
{
std::map<std::string, boost::function<base* (int&, int&)>> factories;
factories["derived"] = boost::bind(boost::factory<derived*>(), _1, _2);
int x = 42;
int y = 51;
std::unique_ptr<base> b{ factories.at("derived")(x,y) };
b->print();
}
// Factory with two initialized inputs args - binding of values not at run time
{
std::map<std::string, boost::function<base* ()>> factories;
factories["derived"] = boost::bind(boost::factory<derived*>(), 42, 51);
std::unique_ptr<base> b{ factories.at("derived")() };
b->print();
}
}
Now consider my code - SimpleClasses.h:
// Dummy base class - non template
class IBaseClass
{
public:
};
// Templatized Derived Base class
template <typename T>
class ConcreteClass : public IBaseClass
{
private:
std::shared_ptr<IBaseClass> m_leftArgument;
std::shared_ptr<IBaseClass> m_leftArgument;
public:
ConcreteClass(std::unique_ptr<IBaseClass>& leftArgument, std::unique_ptr<IBaseClass>& rightArgument)
{
m_leftArgument = leftArgument;
m_rightArgument = rightArgument;
};
virtual T DoSomething()
{
cout << "I did something in Concrete Base Class" << endl;
return T();
}; // This is the main reason for creating T
};
template <typename T>
class ConcreteClassA : ConcreteClass
{
};
template <typename T>
class ConcreteClassB : ConcreteClass
{
};
template <typename T>
class ConcreteClassC : ConcreteClass
{
};
Another File, ClassFactory.h :
#pragma once
#include "SimpleClasses.h"
#include <memory>
#include <map>
#include <boost/functional/overloaded_function.hpp>
#include <boost/functional/factory.hpp>
using namespace std;
// Add More class Keys here
namespace MyClassesNamespace { // These are all string keys
static const string CLASS_A = "specialclassA";
static const string CLASS_B = "specialclassB";
static const string CLASS_C = "specialclassC";
};
enum EMyDataTypes
{
INT8,
FLOAT8,
FLOAT16,
};
// This type def we keep for non templatized base class constructor
typedef boost::function<IBaseClass*(std::unique_ptr<IBaseClass>&, std::unique_ptr<IBaseClass>&)> IBaseClassConstructorFunc_factory;
// Dummy base factory - no template
class UBaseClassTemplateFactory
{
public:
};
template<typename T>
class UClassFactoryTemplate : public UBaseClassTemplateFactory
{
private:
static std::map<string, IBaseClassConstructorFunc_factory> ClassFactoryTemplateMap; // Unique Classes only
public:
UClassFactoryTemplate();
__forceinline static UClassFactoryTemplate*Get()
{
static UClassFactoryTemplate<T> SingletonInstance;
return &SingletonInstance;
}
static std::unique_ptr<IBaseClass<T>> CreateClassTemplatized(string ClassString, std::unique_ptr<IBaseClass> LeftArgument, std::unique_ptr<IBaseClass> RightArgument);
};
// This type def we keep for non templatized base class
typedef boost::function<UBaseClassTemplateFactory*()> ClassFactoryTemplate_factory;
/* This is the instance class that resolves the classes as well as the concrete datatype to be used in UClassFactoryTemplate*/
class UClassFactory
{
private:
UClassFactory();
static std::map<EMyDataTypes, ClassFactoryTemplate_factory> ClassDataTypeTemplateFactoryMap;
public:
__forceinline static UClassFactory *Get()
{
static UClassFactory SingletonInstance;
return &SingletonInstance;
}
static std::unique_ptr<IBaseClass> CreateConcreteClass(string ClassString, std::unique_ptr<IBaseClass> LeftVal, std::unique_ptr<IBaseClass> RightVal, EMyDataTypes someEnumVal = EMyDataTypes::INT8);
};
Finally, in ClassFactory.cpp
#include "ClassFactory.h"
#include <boost/bind.hpp>
/*static, but non-const data members should be defined outside of the class definition
*and inside the namespace enclosing the class. The usual practice is to define it in
*the translation unit (*.cpp) because it is considered to be an implementation detail.
*Only static and const integral types can be declared and defined at the same time (inside class definition):*/
template<typename T>
std::map<string, IBaseClassConstructorFunc_factory> UClassFactoryTemplate<T>::ClassFactoryTemplateMap;
std::map<EMyDataTypes, ClassFactoryTemplate_factory> UClassFactory::ClassDataTypeTemplateFactoryMap;
template<typename T>
inline UClassFactoryTemplate<T>::UClassFactoryTemplate()
{
ClassFactoryTemplateMap[MyClassesNamespace::CLASS_A] = boost::bind(boost::factory<ConcreteClassA<T>*>(), _1, _2);
ClassFactoryTemplateMap[MyClassesNamespace::CLASS_B] = boost::bind(boost::factory<ConcreteClassB<T>*>(), _1, _2);
ClassFactoryTemplateMap[MyClassesNamespace::CLASS_C] = boost::bind(boost::factory<ConcreteClassC<T>*>(), _1, _2);
}
template<typename T>
std::unique_ptr<IBaseClass<T>> UClassFactoryTemplate<T>::CreateClassTemplatized(string ClassString, std::unique_ptr<IBaseClass> LeftArgument, std::unique_ptr<IBaseClass> RightArgument)
{
std::unique_ptr<IBaseClass<T>> someTemplatizedDataTypeInstance{ ClassFactoryTemplateMap.at(ClassString) (LeftArgument,RightArgument) };
return someTemplatizedDataTypeInstance;
}
UClassFactory::UClassFactory()
{
ClassDataTypeTemplateFactoryMap[EMyDataTypes::INT8] = boost::bind(boost::factory<UClassFactoryTemplate<int>*>());
ClassDataTypeTemplateFactoryMap[EMyDataTypes::FLOAT8] = boost::bind(boost::factory<UClassFactoryTemplate<float>*>());
ClassDataTypeTemplateFactoryMap[EMyDataTypes::FLOAT16] = boost::bind(boost::factory<UClassFactoryTemplate<double>*>());
}
std::unique_ptr<IBaseClass> UClassFactory::CreateConcreteClass(string ClassString, std::unique_ptr<IBaseClass> LeftVal, std::unique_ptr<IBaseClass> RightVal, EMyDataTypes someEnumVal)
{
std::unique_ptr<UBaseClassTemplateFactory> BaseOperatorTempFactory{ ClassDataTypeTemplateFactoryMap.at(someEnumVal) };
return BaseOperatorTempFactory->Get()::CreateClassTemplatized(ClassString, LeftVal, RightVal);
}
The question now is, the above code does not even compile let alone run, it says abstract class cannot be instantiated for the templatized map. I just want the UClassFactory to return me correct instantiated class like A,B,C based on a string map with correct datatypes based on an enum. How do I achieve this combination? I wonder what is the correct syntax? Or is my approach inherently flawed? Or there is a nice way to instantiate classes with factory pattern and different datatypes? Please let me know any suggestions/ comments.
Thanks
Alam
I wanted to store a vector of function pointers, each taking different no. of arguments in a class "Store". So, wrote a templated class "Func" that would store the function as a std::function and its arguments in a tuple.
I derived this "Func" class from a non-template base class "IFunc", so that i can store a vector of pointers to this base class in the class "Store".
template<typename... Args>
class Func : public IFunc
{
public:
std::function<void (Args...)> f;
std::tuple<Args...> args;
template <typename F,typename... Ar>
Func(F&& func,Ar&&... arg): f(std::forward<F>(func)),args(std::make_tuple(std::forward<Ar>(arg)...))
{
}
virtual ~NonMemfun()
{
}
//other methods to unpack the tuple and call the function
};
The IFunc class:
class IFunc
{
public:
Ifunc(){}
virtual ~Ifunc(){}
};
The Store class:
class Store
{
std::vector<Ifunc*> funcs;
public:
template<typename... Args,typename... Args2>
void registerfunc(std::string name,int runs,void(*f)(Args...),Args2&&... arg)
{
Func<Args2...>* sample = new Func<Args2...>(f,arg...);
Ifunc* fp = sample;
funcs.push_back(fp);
}
};
I want to iterate through the vector and call each function. To do that i need to do a static cast like this:
Func<>* der = static_cast<Func<>*>(funcs[0]);
When i try to do this, the cast doesn't happen properly. I cannot specify the template paramenters(variadics) since this class(Store) is not aware of them.
I am totally stuck at this place. Something is wrong with my design i guess. Can someone please suggest me a better way to do this. Thank you.
Rather than trying to do a cast from IFunc to Func<>, you should make a pure virtual function, Apply() in IFunc, which Func<> defines as apply(f, args...);. As you iterate over the vector of IFunc pointers, simply call IFunc->Apply(), which will dispatch to the Func<>::Apply() and do the actual apply.
I'm not much of a C++ programmer, but I think you may find this useful.
I'm sure you know that templates are a compile time thing in C++ so your functions need to be known at build time.
With that said, if you do know your functions and you just want to map them to say a string command and then dynamically bind arguments from something like a stream then this code should help you. It is actually able to use a dynamic_cast to retrieve the command from the map.
this snippet is from a school project I did a while back that had a similar goal:
#include <map>
#include <string>
#include <sstream>
#include <tuple>
using namespace std;
class Shell {
class Command {
public:
virtual ~Command() {};
virtual void executeWithArgStream(Shell*, istream& s)=0;
};
template <typename... ArgTypes>
class ShellCommand : public Command {
private:
// FIXME: its probably more apropriate for FuncType to return an int for exit code...
typedef function<void(Shell*, ArgTypes...)> FuncType;
FuncType _f;
tuple<ArgTypes...> args;
template<int... Is>
struct seq { };
template<int N, int... Is>
struct gen_seq : gen_seq<N - 1, N - 1, Is...> { };
template<int... Is>
struct gen_seq<0, Is...> : seq<Is...> { typedef seq<Is...> type; };
template<size_t I = 0, class ...P>
typename std::enable_if<I == sizeof...(P)>::type
// template for functions with no arguments
parseArgs(istream& is, std::tuple<P...> &) {}
template<size_t I = 0, class ...P>
typename std::enable_if<I < sizeof...(P)>::type
parseArgs(istream& is, std::tuple<P...> & parts) {
// this is the magic bit that takes a tuple of pointers (representing the command arguments)
// created at compile time and creates new instances of each argument type and populates it from
// the given input stream :D
auto& part = std::get<I>(args);
// hmmm should we delete or recycle...
delete part;
part = new typeof(*part);
is >> *part;
parseArgs<I + 1>(is, parts);
}
template<int ...S>
void callFunc(Shell* shell, seq<S...>) {
_f(shell, get<S>(args) ...);
}
public:
static constexpr size_t numArgs = sizeof...(ArgTypes);
ShellCommand(FuncType f) : _f(f) {};
void operator()(Shell* shell, ArgTypes... args) {
_f(shell, args...);
};
void executeWithArgStream(Shell* shell, istream& s)
{
parseArgs(s, args);
callFunc(shell, typename gen_seq<sizeof...(ArgTypes)>::type());
};
};
private:
typedef shared_ptr<Command> CommandPtr;
typedef map<string, CommandPtr> FMap;
FMap _cmdMap;
ostream& _out;
istream& _in;
public:
Shell(istream& is = cin, ostream& os = cout)
: _out(os), _in(is)
{
// populate
_cmdMap.insert(pair<string, CommandPtr>("chdir", make_shared<ShellCommand<string*>>(&Shell::chdir)));
_cmdMap.insert(pair<string, CommandPtr>("list", make_shared<ShellCommand<>>(&Shell::list)));
_cmdMap.insert(pair<string, CommandPtr>("count", make_shared<ShellCommand<>>(&Shell::count)));
};
int run();
// FIXME: its probably more apropriate for execute to return an int for exit code...
template <typename... ArgTypes>
void execute(string& command, ArgTypes... args);
void executeWithArgStream(string& command, istream& istr);
// shell commands:
// any command parameters must be done as a pointer!
// the magic that parses string arguments into real types depends on it!
void list() {
list command
};
void chdir(string* dir) {
// chdir command
};
void count() {
// count command
};
};
template <typename... ArgTypes>
void Shell::execute(string& command, ArgTypes... args)
{
typedef ShellCommand<ArgTypes...> CommandType;
CommandType* c = dynamic_cast<CommandType*>(_cmdMap[command].get());
// TODO: neeed to diferentiate between invalid commands and some kind of dynamic_cast failure
if (c) {
(*c)(this, args...);
} else {
// dynamic cast failure
throw runtime_error("Broken Implementation for:" + command);
}
}
void Shell::executeWithArgStream(string& command, istream& istr)
{
Command* c = _cmdMap[command].get();
if (c) {
c->executeWithArgStream(this, istr);
} else {
throw runtime_error("Invalid Shell Command: " + command);
}
}
int Shell::run()
{
do {
string cmd, argString;
_out << _currentDir->name() << "> ";
_in.clear();
_in >> cmd;
if (cmd == "q") {
return 0;
}
if (_in.peek() == ' ')
_in.ignore(1, ' ');
getline(cin, argString);
if (_cmdMap[cmd]) {
try {
if (argString.length()) {
istringstream s(argString);
executeWithArgStream(cmd, s);
} else {
execute(cmd);
}
} catch (runtime_error& e) {
_out << e.what() << endl;
}
} else {
_out << "unrecognized command: " << cmd << endl;
}
} while (true);
}
int main(int argc, const char * argv[])
{
// start the interactive "shell"
Shell shell();
return shell.run();
}