how to create a map with value as templatized function pointer - c++

Below code doesn't compile, please help me where I'm missing. I have member functions with different return types and I need to call those functions by just passing a string name. So I have created a map, Below is the example which matches my requirement, but I'm not able to compile.
template<typename T1>
shared_ptr<T1> GetBasicClassInfo()
{
T1 obj;
shared_ptr<T1> pobj( new T1);
return pobj;
}
class BasicClass
{
public:
std::string GetValue()
{
return "Successfull";
}
int GetInt()
{
return 5;
}
};
template<typename T>
std::map<std::string, std::function<T()>> GetPropertyValue ={
{"int",&GetBasicClassInfo<BasicClass>()->GetInt},
{"string",&GetBasicClassInfo<BasicClass>()->GetValue}
};
int main()
{
cout<<GetPropertyValue["int"]()<<endl;
cout<<GetPropertyValue["string"]();
return 0;
}

Related

How can I return an arbitrary derived class of an abstract generic class and call its generic methods?

I've got an abstract class that uses variable template.
template <class T>
class Abstract
{
public:
virtual void print(T t) = 0;
};
There can be any derivatives of the class like so:
class A : public Abstract<std::string>
{
public:
void print(std::string str)
{
std::cout << str << std::endl;
}
};
class B : public Abstract<int>
{
public:
void print(int number)
{
std::cout << std::to_string(number) << std::endl;
}
};
Now I want a function to return one of these derivatives so I can execute the print method. And here is my Problem:
template (class T); // error here
Abstract<T> &f(int n) // what should the return type look like?
{
if (n == 0)
{
A a{};
return a;
}
else
{
B b{};
return b;
}
}
int main()
{
A a{f(0)};
a.print("foo");
B b{f(1)};
b.print(42);
return 0;
}
So how is it be possible to return a class with unknown parameter type and call its methods?
I already tried returning derived classes without templates which works fine. As soon as templates are added code wont compile. I also tried void* and reinterpret_cast. Problem here is that I have manually to decide to what type to cast to.
So how can I return an arbitrary superclass of an abstract generic class and call its generic methods?
I think inheritance is the wrong approach here. Instead I would use specialization instead:
template<typename T>
struct Foo;
template<>
struct Foo<std::string>
{
void print(std::string const& s)
{
std::cout << s << '\n';
}
};
template<>
struct Foo<int>
{
void print(int value)
{
std::cout << value << '\n';
}
};
Then you don't need a selector to pick the object to create, just the correct type:
int main()
{
Foo<std::string> f1;
f1.print("hello");
Foo<int> f2;
f2.print(123);
}
If you really need a factor function, then it could be created like this:
template<typename T>
Foo<T> create()
{
return Foo<T>();
}
And use like
int main()
{
auto f1 = create<std::string>();
f1.print("hello");
auto f2 = create<int>();
f2.print(123);
}

How can I handle returning an error from a getter method?

I am wondering how can I return an error from a getter method in this situation?
class A
{
private:
int a;
int b;
public:
const int& get(int i)
{
if (i == 1) return a;
else if (i == 2) return b;
// else... what to do here? I get a warning if I don't put anything.
}
};
NOTE: You don't need to return a const int& to your member class, int is enough.
The C++ way for this is Exceptions, but i don't like them and i want suggest some other way based on some situations:
The Getter function must do some operations and then return the result; In this case we could return a std::pair<boo, Type_Of_Result> which is boolean type indicate "It's a successful operation ?":
class A {
private:
int m_value;
public:
A(const int value):
m_value(value) {
}
template<typename T>
using return_t = std::pair<bool, T>;
return_t<int> get() const {
return { true, m_value };
}
};
Okay we got the return value status, But if it fails, how to find why?: In this case we could create a Result class which take care of Error message and return value:
template <typename T>
struct Result {
T return_value;
bool its_okay;
std::string message;
};
class A {
// ...
Result<int> get() const {
return { m_value, true, "All right" };
}
};

C++ User-defined type conversion failure

template<typename T>
class Pack
{
private:
std::function<T()> _Func = nullptr;
public:
Pack()
{
}
Pack(std::function<T()> func)
: _Func(func)
{
}
~Pack()
{
}
operator T()
{
return _Func();
}
};
What I use is operator T, I want to call _Func implicitly but I cannot even do it explicitly. It seems right but actually error C2440 #MSVC. I use it in two ways:
static member of class (succeeded);
member of class (failed)
(I don't know whether it matters or not)
I'm really wondering why it performs in two ways, and more importantly, how I can put it into my class as a non-static member and successfully call the operator T.
Member of the class:
struct test
{
test()
{
p_ = Pack<int>(std::bind(&test::foo, *this));
}
int foo()
{
std::cout << "test::foo" << std::endl;
return 5;
}
Pack<int> p_;
};
int main()
{
test t;
int x = t.p_;
return 0;
}
This works fine on VS 2013 EE.

Use function pointer in template class

This is a selection of my class
template <typename TValue, typename TPred = std::less<TValue> >
class BinarySearchTree {
public:
BinarySearchTree<TValue, TPred> &operator=(BinarySearchTree<TValue, TPred> const &tree) {
if (this != &tree) {
tree.VisitInOrder(Insert);
}
return *this;
}
bool Insert(TValue const &value) {
return m_Insert(value, pRoot);
}
template <typename TVisitor> void VisitInOrder(TVisitor visitor) const;
...
};
and the following sequence wont work: VisitInOrder(Insert) because my compiler says that there are arguments missing
but my main looks like this and there i can use the function without its arguments:
void Print(int const x) { cout << x << endl; }
int main() {
BinarySearchTree<int> obj1, obj2, obj3;
obj1.Insert(10);
obj1.VisitInOrder(Print);
return 0;
}
full code here: http://pastebin.com/TJmAgwdu
Your function Insert is a member function, which means it accepts an implicit this pointer. You have to use std::bind() if you want to get a unary functor out of Insert():
if (this != &tree) {
tree.VisitInOrder(
std::bind(&BinarySearchTree::Insert, this, std::placeholders::_1));
}
Here is a live example showing the program compiling when the following assignment is present:
obj3 = obj1;

Why is the dtor being called (using annoymous/lambda func)

I am trying to mimic a finally like effect. So i thought i should run a quick dirty test.
The idea was to use Most Important const to stop destruction and to put the finally block in a lambda. However apparently i did something wrong and its being called at the end of MyFinally(). How do i solve this problem?
#include <cassert>
template<typename T>
class D{
T fn;
public:
D(T v):fn(v){}
~D(){fn();}
};
template<typename T>
const D<T>& MyFinally(T t) { return D<T>(t); }
int d;
class A{
int a;
public:
void start(){
int a=1;
auto v = MyFinally([&]{a=2;});
try{
assert(a==1);
//do stuff
}
catch(int){
//do stuff
}
}
};
int main() {
A a;
a.start();
}
My Solution code (Note: You can not have two finally in the same block. as expect. But still kind of dirty)
#include <cassert>
template<typename T>
class D{
T fn; bool exec;
public:
D(T v):fn(v),exec(true){}
//D(D const&)=delete //VS doesnt support this yet and i didnt feel like writing virtual=0
D(D &&d):fn(move(d.fn)), exec(d.exec) {
d.exec = false;
}
~D(){if(exec) fn();}
};
template<typename T>
D<T> MyFinally(T t) { return D<T>(t); }
#define FINALLY(v) auto OnlyOneFinallyPlz = MyFinally(v)
int d;
class A{
public:
int a;
void start(){
a=1;
//auto v = MyFinally([&]{a=2;});
FINALLY([&]{a=2;});
try{
assert(a==1);
//do stuff
}
catch(int){
FINALLY([&]{a=3;}); //ok, inside another scope
try{
assert(a==1);
//do other stuff
}
catch(int){
//do other stuff
}
}
}
};
void main() {
A a;
a.start();
assert(a.a==2);
}
Funny enough, if you remove the & in MyFinally in the original code it works -_-.
// WRONG! returning a reference to a temporary that will be
// destroyed at the end of the function!
template<typename T>
const D<T>& MyFinally(T t) { return D<T>(t); }
You can fix it my introducing a move constructor
template<typename T>
class D{
T fn;
bool exec;
public:
D(T v):fn(move(v)),exec(true){}
D(D &&d):fn(move(d.fn)), exec(d.exec) {
d.exec = false;
}
~D(){if(exec) fn();}
};
And then you can rewrite your toy
template<typename T>
D<T> MyFinally(T t) { return D<T>(move(t)); }
Hope it helps. No "const reference" trick is needed when you work with auto. See here for how to do it in C++03 with const references.
Your code and Sutter's are not equivalent. His function returns a value, yours returns a reference to an object that will be destroyed when the function exits. The const reference in the calling code does not maintain the lifetime of that object.
The problem stems from the use of a function maker, as demonstrated by Johannes.
I would argue that you could avoid the issue by using another C++0x facility, namely std::function.
class Defer
{
public:
typedef std::function<void()> Executor;
Defer(): _executor(DoNothing) {}
Defer(Executor e): _executor(e) {}
~Defer() { _executor(); }
Defer(Defer&& rhs): _executor(rhs._executor) {
rhs._executor = DoNothing;
}
Defer& operator=(Defer rhs) {
std::swap(_executor, rhs._executor);
return *this;
}
Defer(Defer const&) = delete;
private:
static void DoNothing() {}
Executor _executor;
};
Then, you can use it as simply:
void A::start() {
a = 1;
Defer const defer([&]() { a = 2; });
try { assert(a == 1); /**/ } catch(...) { /**/ }
}
Well the problem is explained by others, so I will suggest a fix, exactly in the same way Herb Sutter has written his code (your code is not same as his, by the way):
First, don't return by const reference:
template<typename T>
D<T> MyFinally(T t)
{
D<T> local(t); //create a local variable
return local;
}
Then write this at call site:
const auto & v = MyFinally([&]{a=2;}); //store by const reference
This became exactly like Herb Sutter's code.
Demo : http://www.ideone.com/uSkhP
Now the destructor is called just before exiting the start() function.
A different implementation which doesn't use auto keyword anymore:
struct base { virtual ~base(){} };
template<typename TLambda>
struct exec : base
{
TLambda lambda;
exec(TLambda l) : lambda(l){}
~exec() { lambda(); }
};
class lambda{
base *pbase;
public:
template<typename TLambda>
lambda(TLambda l): pbase(new exec<TLambda>(l)){}
~lambda() { delete pbase; }
};
And use it as:
lambda finally = [&]{a=2; std::cout << "finally executed" << std::endl; };
Looks interesting?
Complete demo : http://www.ideone.com/DYqrh
You could return a shared_ptr:
template<typename T>
std::shared_ptr<D<T>> MyFinally(T t) {
return std::shared_ptr<D<T>>(new D<T>(t));
}