I got strange code and have to extend it. But instead of copy paste many many times i decided to create a template. But get caught by a terrible rock.
Here is an example code:
template<typename T>
class anyClass {};
template<typename T>
class Outer : public anyClass<T>
{
public:
using value_t = T;
class Inner
{
virtual void foo(value_t);
};
};
class specializer : protected Outer::Inner
{
virtual void foo(int) override {}
}
I have to extend virtual void foo(value_t) in specializer.
Example:
class specializer : protected Outer::Inner
{
virtual void foo(int) override {}
virtual void foo(float) override {}
virtual void foo(string) override {}
virtual void foo(bar) override {}
// And so on...
}
Question 1: Why works the example, although class specializer : protected Outer::Inner miss a param?
All overloadings do nearly the same. I created already the function.
template<typename anyType>
void meow( anyType )
{
/***/
}
My problem is here:
virtual void foo(anytype value) //<< replace anytype with what?
{
meow<anytype>( value );
}
I need the type Outer::value_T but i don't know how to get it.
Question 2: How can i use meow by calling foo ?
Feel free to ask for more information.
UPDATE
I looked again in the origin code and realised, that i've overlooked an important using/typedef.
The working code looks like:
class specializer : protected Outer<int, float, string, bar>::Inner //Yes a variadic-template
{
virtual void foo(int) override {}
virtual void foo(float) override {}
virtual void foo(string) override {}
virtual void foo(bar) override {}
// And so on...
}
So Question 1 is solved.
Why works the example, although class specializer : protected Outer::Inner miss a param?
The example does not work. It does not work because Outer is not a type. Also, you override multiple overloads of foo even though inner has only one foo. There are several syntax errors too. If it appears to work, then the compiler is doing something non-standard.
About your second question:
virtual void foo(anytype value) //<< replace anytype with what?
You replace it with the type whose overload you intend to override. For example, if you intend to override foo(int), then replace anytype with int.
Question 2: How can i use meow by calling foo ?
Simply call meow in foo.
You would have to make specializer a template class.
#include <iostream>
template<typename T> void meow(T x)
{
std::cout << x << std::endl;
}
template<typename T>
class anyClass {};
template<typename T>
class Outer : public anyClass<T>
{
public:
using value_t = T;
class Inner
{
virtual void foo(Outer<T>::value_t);
};
};
template<typename T>
class specializer : protected Outer<T>::Inner
{
virtual void foo(T x) override
{
meow(x);
}
};
I wonder how this would help you to change the behavior in Outer or anyClass because you have not shown code which shows where and how Inner is actually used. Without that, it's just guessing.
I have the feeling that what you are actually trying to achieve is to pass a function (or Strategy?) to you Outer class, represented by Inner in your code. That would be better done by passing it as a template argument.
template<typename T>
class anyClass {};
template<typename T, typename Inner = meow<T>>
class Outer : public anyClass<T>
{
public:
using value_t = T;
// somewhere in your code
Inner i;
i.meow( any_value );
};
You can also pass a std::function to the constructor.
template
class anyClass {};
template<typename T>
class Outer : public anyClass<T>
{
public:
using value_t = T;
Outer( std::function<void (value_t)> inner);
// somewhere in your code
i.meow( any_value );
std::function<void (value_t)> i;
};
Originally I simplyfied a little bit to much.
Here is the compileable example of my problem: http://ideone.com/9U7J1a
I removed all unconducive code. I know the design is horrible but i have no influence on it.
class bar {};
class string {};
template<typename _T>
class ModelContainer
{
public:
using value_type = _T;
class Delegate {
public:
virtual void foo( value_type value);
};
};
template< typename... _Ts >
class ModelManager__AbstractBase : protected ModelContainer< _Ts >...
{
public:
class Delegate : public ModelContainer< _Ts >::Delegate... {
public:
virtual ~Delegate( ) = default;
};
};
using ModelManager__Base = ModelManager__AbstractBase<
int,
float,
string,
bar
>;
class ModelManager : public ModelManager__Base {
/* Some functions */
};
class spezializer : ModelManager::Delegate
{
public:
virtual ~spezializer() = default;
//Uncommend to see my error
// virtual void foo( value_type value) override // << value_type unknown
// {/* Calling everytime the same method, no matter which value_type*/}
};
Related
How to create many classes to act like implementer for an interface class, while avoid v-table cost as possible, and still enable static casting to the interface?
For a simple case, it can be achieved like in the below example.
Example
Library Code :-
class I{ //interface
public: virtual void i1()=0;
};
template<class Derived>class Router : public I{
public: virtual void i1()final{
//in real case it is very complex, but in the core is calling :-
static_cast<Derived*>(this)->u1();
}
};
User Code :-
class User : public Router<User>{
public: void u1(){ std::cout<<"hi"<<std::endl; }
};
int main() {
User u;
u.i1(); //<-- no v-table cost
I* i=&u;
i->i1(); //<-- has v-table cost (OK)
}
Full demo
Question
How to extend the above feature to support 2 routes or more?
The below code is uncompilable, but it depicts my dream. (full demo).
Library Code :-
class I{ //interface
public: virtual void i1()=0;
public: virtual void i2()=0;
};
template<class Derived>class RouterI1U1 : public I{
public: virtual void i1()final{ static_cast<Derived*>(this)->u1(); }
};
template<class Derived>class RouterI1U2 : public I{
public: virtual void i1()final{ static_cast<Derived*>(this)->u2(); }
};
template<class Derived>class RouterI2U1 : public I{
public: virtual void i2()final{ static_cast<Derived*>(this)->u1(); }
};
template<class Derived>class RouterI2U2 : public I{
public: virtual void i2()final{ static_cast<Derived*>(this)->u2(); }
};
User Code :-
The one who want to use the above library, can easily pick whatever "route" he want.
derived from RouterI1U2<User> and RouterI2U1<User> or
derived from RouterI1U1<User> and RouterI2U2<User> or
derived from {RouterI1U1<User> or RouterI1U2<User>} and implement i2() with final manually or
derived from {RouterI2U2<User> or RouterI2U1<User>} and implement i1() with final manually or
implement i1() and i2() with final manually
Here is an dreamed example of usage.
class User : public RouterI1U2<User>,public RouterI2U1<User>{
public: void u1(){ std::cout<<"hi1"<<std::endl; }
public: void u2(){ std::cout<<"hi2"<<std::endl; }
};
int main() {
User u;
u.i1(); //<-- no v-table cost
I* i=&u;
i->i1(); //<-- has v-table cost (OK)
}
My poor solution
class I{ //interface
public: virtual void i1()=0;
public: virtual void i2()=0;
};
template<class Derived> class RouterI1U2_I2U1 : public I{ //group it
public: virtual void i1()final{ static_cast<Derived*>(this)->u2(); }
public: virtual void i2()final{ static_cast<Derived*>(this)->u1(); }
};
class User : public RouterI1U2_I2U1<User>{
public: void u1(){ std::cout<<"hi1"<<std::endl; }
public: void u2(){ std::cout<<"hi2"<<std::endl; }
};
It works (demo), but offer less modularity. (low re-usability)
I have to pack RouterI1U2 and RouterI2U1 to RouterI1U2_I2U1 manually.
It may not apply in your case, but could be useful to other reading the question as well.
I suggest you to use the concept-model idiom for this particular case. The goal of this is to separate the polymorphism implementation and the implementation of those class themselves into different part. Here, I becomes a polymorphic wrapper around any class that has i1 and i2 member functions:
class I {
// The interface is internal, invisible to outside
// We use this as a type erasure technique and polymorphism
struct Concept {
virtual void i1() = 0;
virtual void i2() = 0;
};
// The single implementation that directly
// extend the interface is the model. T is the user class.
// T must have i1 and i2 function, because we call them.
template<typename T>
struct Model : Concept {
// The user class.
// If you want, you can use a reference there if you
// need references semantics with I
T user;
Model (T u) : user{std::move(u)} {}
// The only implementation of i1 is to call i1 from the user class
void i1() override {
user.i1();
}
void i2() override {
user.i2();
}
};
// Or use a shared, or use SBO
std::unique_ptr<Concept> concept;
public:
// When we make an I, we must provide a user class.
// If the user class had i1 and i2, it will compile.
// If Model takes a reference, use a reference there too.
template<typename T>
I(T model) : concept{std::make_unique<Model<T>>(std::move(model))} {}
void i1() {
concept->i1();
}
void i2() {
concept->i2();
}
};
Then, your classes that provide implementations becomes like this:
template<class Derived>
struct RouterI1U1 { // no Inheritance needed
void i1() { static_cast<Derived*>(this)->u1(); }
};
template<class Derived>
struct RouterI1U2 {
void i1() { static_cast<Derived*>(this)->u2(); }
};
template<class Derived>
struct RouterI2U1 {
void i2() { static_cast<Derived*>(this)->u1(); }
};
template<class Derived>
struct RouterI2U2 {
void i2() { static_cast<Derived*>(this)->u2(); }
};
Since these i1 and i2 only needs to be "there" in order to fit into the Model<T> class, no overriding is needed, so no virtual inheritance.
It would effectively look like this when used:
struct User : RouterI2U2<User> {
void i1() {}
void u2() {}
};
As you can see, we don't have any virtual method. The polymorphism is an implementation detail of I. Since this class have all required member functions, the I class will allow it.
And using the class I too is quite simple. Let User2 be another user class that fits I requirements:
User2 user2;
user2.i1(); // no vtable, so no vtable overhead possible
I myI{user2}; // works!
myI.i2(); // calls u2, with vtable
std::vector<I> v;
v.emplace_back(User2{});
v.emplace_back(User{}); // simple heh?
Here's how you can remove the router classes, and implement this thing with an "or" style interface. I mean an interface that allows you to implement something or something else.
In the Model<T> class, you can check if i1 and i2 exists. If there are not existing, you can provide an implementation that calls u1 and u2 instead.
We start that by making type traits that can tell us if a particular type T has the member function i1 or i2:
template<typename...>
using void_t = void;
template<typename, typename>
struct has_i1 : std::false_type {};
template<typename T>
struct has_i1<T, void_t<decltype(std::declval<T>().i1())>> : std::true_type {};
template<typename, typename>
struct has_i2 : std::false_type {};
template<typename T>
struct has_i2<T, void_t<decltype(std::declval<T>().i2())>> : std::true_type {};
Now, we can change our model implementation to call u1 or u2 if i1 and i2 are not there:
template<typename T>
struct Model : Concept {
T user;
Model(T u) : user{std::move(u)} {}
void i1() override {
i1_helper(user);
}
void i2() override {
i2_helper(user);
}
private:
template<typename U>
auto i1_helper(U& u) -> std::enable_if_t<has_i1<U>::value> {
// Call i1 if has i1
u.i1();
}
template<typename U>
auto i1_helper(U& u) -> std::enable_if_t<!has_i1<U>::value> {
// Call u1 if has not i1
u.u1();
}
template<typename U>
auto i2_helper(U& u) -> std::enable_if_t<has_i2<U>::value> {
// Call i2 if has i2
u.i2();
}
template<typename U>
auto i2_helper(U& u) -> std::enable_if_t<!has_i2<U>::value> {
// Call u2 if has not i2
u.u2();
}
};
Now, your user classes are the simplest possible.
struct User1 {
void i1() {}
void i2() {}
};
struct User2 {
void i1() {}
void u2() {}
};
struct User3 {
void u1() {}
void i2() {}
};
struct User4 {
void u1() {}
void u2() {}
};
Use virtual inheritance.
template<class Derived>class RouterI1U1 : public virtual I{
etc. makes the code compilable.
I have a method in a baseclass that needs the type passed to it for some type-related operations (lookup, size, and some method invocation). Currently it looks like this:
class base
{
template<typename T>
void BindType( T * t ); // do something with the type
};
class derived : public base
{
void foo() { do_some_work BindType( this ); }
};
class derivedOther : public base
{
void bar() { do_different_work... BindType( this ); }
};
However, I wonder if there's a way to get the caller's type without having to pass this so that my callpoint code becomes:
class derived : public base
{
void foo() { BindType(); }
};
Without the explicit this pointer. I know that I could supply the template parameters explicitly as BindType<derived>(), but is there a way to somehow extract the type of the caller in some other way?
There's no magical way to get the caller's type, but you can use CRTP (as a comment mentions) in order to automate this behavior, at the cost of a bit of code complexity:
class base
{
template<typename T>
void BindType(); // do something with the type
};
template <class T>
class crtper : base
{
void BindDerived { BindType<T>(); }
}
class derived : public crtper<derived>
{
void foo() { do_some_work BindDerived(); }
};
class derivedOther : public crtper<derivedOther>
{
void bar() { do_different_work... BindDerived(); }
};
Edit: I should mention, I would kind have expected that foo would be a virtual function, defined without implementation in base. That way you would be able to trigger the action directly from the interface. Although maybe you have that in your real code, but not in your example. In any case, this solution is perfectly compatible with this.
Edit2: After question edit, edited to clarify that solution still applies.
If you want to avoid BindType<derived>(), consider (a bit verbose, I agree) BindType<std::remove_reference<decltype(*this)>::type>(); to avoid passing a parameter. It gets resolved at compile-time and avoids run-time penalties.
class base
{
protected:
template<typename T>
void BindType() { cout << typeid(T).name() << endl; } // do something with the type
};
class derived : public base
{
public:
void foo()
{
BindType<std::remove_reference<decltype(*this)>::type>();
}
};
It will not work as you expect
The result of foo() might be different of what you expect:
class derived : public base // <= YOU ARE IN CLASS DERIVED
{
public:
void foo() { BindType( this ); } // <= SO this IS OF TYPE POINTER TO DERIVED
};
The template paramter is deducted at compile time, so that it will be derived*. If you would call foo() from a class derived_once_more derived from derived, it would still use the type derived*.
Online demo
But you can get rid of the dummy parameter*
You may use decltype(this) to represent the typename of a variable. It's still defined at compile time:
class base
{
public:
template<typename T>
void BindType( )
{
cout << typeid(T*).name()<<endl; // just to show the type
}
virtual ~base() {}; // for typeid() to work
};
class derived : public base
{
public:
void foo() { BindType<decltype(this)>( ); }
};
Online demo
Edit: other alternatives
As template parameters need to be provided at compile-time and not a run time, you can use:
template parameter deduction (your first code snippet)
decltype (see above)
if you intend to add this in all the derived classes you could use a macro to get it done, using one of the above mentionned solution
you could use the CRTP pattern (already explained in another answer).
A possible solution that avoids the intermediate class of the CRTP follows:
class base {
using func_t = void(*)(void *);
template<typename T>
static void proto(void *ptr) {
T *t = static_cast<T*>(ptr);
(void)t;
// do whatever you want...
}
protected:
inline void bindType() {
func(this);
}
public:
template<typename T>
base(T *): func{&proto<T>} {}
private:
func_t func;
};
struct derived1: base {
derived1(): base{this} {}
void foo() {
// ...
bindType();
}
};
struct derived2: base {
derived2(): base{this} {}
void bar() {
// ...
bindType();
}
};
int main() {
derived1 d1;
d1.foo();
derived2 d2;
d2.bar();
}
The basic idea is to exploit the fact that the this pointers in the constructor of the derived classes are of the desired types.
They can be passed as a parameter of the constructor of the base class and used to specialize a function template that do the dirty job behind the hood.
The type of the derived class is actually erased in the base class once the constructor returns. Anyway, the specialization of proto contains that information and it can cast the this pointer of the base class to the right type.
This works fine as long as there are few functions to be specialized.
In this case there is only one function, so it applies to the problem pretty well.
You can add a static_assert to add a constraint on T, as an example:
template<typename T>
base(T *t): func{&proto<T>} {
static_assert(std::is_base_of<base, T>::value, "!");
}
It requires to include the <type_traits> header.
Brief:
I want to make sure a derived class implements a member function required by a function within the parent CRTP class.
Detail:
I have some code like this
class Base
{
public:
class Params
{
public:
virtual ~Params() {}
};
virtual void myFunc( Params& p ) = 0;
};
template< typename T >
class CRTP : public Base
{
public:
virtual void myFunc( Base::Params& p ) override
{
typename T::Params& typedParams = dynamic_cast<typename T::Params&>( p );
static_cast<T*>( this )->myFunc( typeParams );
}
};
class Imp : public CRTP<Imp>
{
public:
class Params : public CRTP<Imp>::Params
{
public:
virtual ~Params() {}
int x, y, z;
};
virtual void myFunc( Imp::Params& p );
};
The intention is that I can have multiple Imp child classes all doing different things in myFunc and accepting their own required parameters. The interface provided by Base is then utilized by higher level functions that only need to have a pointer/reference of type Base::Params and Base. My problem is making sure that any Imp provides a specialized myFunc. To avoid infinite recursion Imp must implement myFunc.
My first try was adding a pure virtual function to CRTP
virtual void myFunc( typename T::Params& p ) = 0;
but that doesn't work as Imp hasn't been fully defined when CRTP is being defined. This question uses a static_assert which made me think of doing the same with the static_assert within CRTP::myFunc. Except I'm not sure what should be the expression in the static assertion for a non-static function.
Can I use a static_assert for what I need?
Is that the best/cleanest way to ensure the derived class has the needed function?
Have I got carried away with my class design and there is a better way of doing things?
Thanks.
Why not just use a different name for the function? Then you will have a compilation error for each derivation of CRTP class without and implementation. Consider this:
class Base
{
public:
class Params
{
public:
virtual ~Params() {}
};
virtual void myFunc( Params& p ) = 0;
};
template< typename T >
class CRTP : public Base
{
public:
virtual void myFunc( Base::Params& p ) final override
{
typename T::Params& typedParams = dynamic_cast<typename T::Params&>( p );
static_cast<const T*>( this )->myFuncImp( typedParams );
}
};
class Imp : public CRTP<Imp>
{
public:
class Params : public CRTP<Imp>::Params
{
public:
virtual ~Params() {}
int x, y, z;
};
};
int main(int argc, char** argv)
{
Imp imp;
}
Compilation fails since there is no myFuncImp provided by Imp.
You may break dynamic polymorphism and switch to static polymorphism:
#include <iostream>
#include <type_traits>
class Base
{
public:
class Params
{
public:
virtual ~Params() {}
};
virtual ~Base() {}
virtual void myFunc(Params& p) = 0;
};
namespace Detail {
// Helper for the static assertion
// Omit this if "‘void CRTP<T>::myFunc(Base::Params&) [with T = Imp]’ is private" is good enough
struct is_MyFunc_callable_implementation
{
template<typename Object, typename Params>
static decltype(std::declval<Object>().myFunc(std::declval<Params&>()), std::true_type())
test(int);
template<typename Object, typename Params>
static std::false_type
test(...);
};
template<typename Object, typename... A>
using is_MyFunc_callable = decltype(is_MyFunc_callable_implementation::test<Object, A...>(0));
// Helper function to break recursion
template<typename Object, typename Params>
inline void invokeMyFunc(Object& object, Params& params) {
static_assert(is_MyFunc_callable<Object, Params>::value, "The derived class is missing 'MyFunc'");
object.myFunc(params);
}
} // namespace Detail
template<typename T>
class CRTP: public Base
{
private:
// Make this final!
virtual void myFunc(Base::Params& p) override final
{
static_assert(std::is_base_of<Base, T>::value, "T must derive from CRTP");
typename T::Params& typeParams = dynamic_cast<typename T::Params&>(p);
Detail::invokeMyFunc(static_cast<T&>(*this), typeParams);
}
};
class Imp: public CRTP<Imp>
{
public:
class Params: public CRTP<Imp>::Params
{
public:
int x = 1;
int y = 2;
int z = 3;
};
// Without this function:
// error: static assertion failed: The derived class is missing 'MyFunc'
// error: ‘void CRTP<T>::myFunc(Base::Params&) [with T = Imp]’ is private
#if 0
void myFunc(Params& p) {
std::cout << p.x << p.y << p.z << '\n';
}
#endif
};
int main()
{
Imp imp;
Base* base = &imp;
Imp::Params params;
base->myFunc(params);
}
However, my opinion is: The base class design is a failure and the code above is just a work around.
The idea of using a different name for the member of derived classes (as in Rudolfs Bundulis answer) is good. However, I would make this a protected method so that users are not tempted to try using it.
Also, using Derived::Params in the CRTP base raises additional complications (since Derived=Imp is not fully declared at point of its use in CRTP<Imp>), so best keep Base::Params as the function parameter throughout.
struct Base // public user interface
{
struct Params { virtual ~Params() {} };
virtual void myFunc( Params& ) = 0;
};
namespace details { // deter clients from direct access
template< typename Derived >
struct CRTP : Base
{
virtual void myFunc( Params& p ) final // cannot be overridden
{
static_cast<Derived*>( this )->myFuncImp(p);
}
};
class Imp : public CRTP<Imp>
{
struct Params : CRTP<Imp>::Params { int x, y, z; };
void myFuncImpDetails( Params* );
protected: // protected from clients
void myFuncImp( Base::Params& p )
{
auto pars=dynamic_cast<Params*>(&p);
if(pars)
myFuncImpDetails(pars);
else
throw std::runtime_error("invalid parameter type provided to Imp::myFunc()");
}
};
} // namespace details
Let's say I have the following template class:
template<typename T>
class A
{
public:
// Lots of functions...
void someFunc(T obj)
{
// T must implement this function in order to be usable within class A.
obj.interfaceFunc();
}
};
This works fine, as the object I will use with the template class implements interfaceFunc().
However, if I pass a pointer to the template class then the compilation fails because the dereference syntax is incorrect. Because the template class contains a lot of other functions that I don't want to copy/paste into another partial specialisation if I can possibly help it, I have changed my class definition as follows:
template<typename T>
class A
{
public:
// Lots of functions...
virtual void virtualHelperFunction(T* obj)
{
// We should never be here in the base class.
assert(false);
}
void someFunc(T obj)
{
// Call the virtual function.
virtualHelperFunction(&obj);
}
};
// Partial specialisation 1
template<typename T>
class B : public A<T>
{
public:
// ...
virtual void virtualHelperFunction(T* obj)
{
obj->interfaceFunc();
}
};
// Partial specialisation 2
template<typename T*>
class B : public A<T*>
{
public:
// ...
virtual void virtualHelperFunction(T* obj)
{
obj->interfaceFunc();
}
};
However, when virtualHelperFunction() is called, on an instance of B but when inside the someFunc() function of the parent A, it hits the assertion error.:
B<SomeObject> instance;
instance.someFunc(SomeObject()); // Assertion failure.
I've tried messing around with function pointers to solve this but I'm still fairly new to them, and the non-static pointer syntax confused me a bit. I'm assuming one could define a member pointer to the virtualHelperFunction() which is set to point to the base class version in A's constructor, but which is then overwritten in B's constructor to point to B's function. If so, would anyone be able to demonstrate the correct syntax to do this?
Thanks.
EDIT: If context is needed, the template class is an octree node which stores a hash table of type T. The interface function required is that the object can return a bounding box, in order for recursive insertion to function depending on whether the object's bounds intersect with the tree node's bounds.
https://github.com/x6herbius/crowbar/blob/qt3d-experimental/Modules/Octree/inc/worldculltreenode.h
https://github.com/x6herbius/crowbar/blob/qt3d-experimental/Modules/Octree/inc/worldculltreenode.tcc
This seems way too complicated. Why specialize the entire class if you just need one tiny bit specialized? All you need is a small utility that says "dereference this if it's a pointer, otherwise leave it alone". It could look like this:
template <typename T>
T& deref_if_pointer(T& t) { return t; }
template <typename T>
T& deref_if_pointer(T* t) { return *t; }
// ...
void someFunc(T obj) {
deref_if_pointer(obj).interfaceFunc();
}
You can easily extend deref_if_pointer to various smart pointers as well; just add another overload.
I'm not really sure what it is that you want to accomplish, so I'll have to guess. In what way does the following not satisfy your problem?
class A
{
public:
// Lots of functions...
void someFunc(T* obj)
{
// T must implement this function in order to be usable within class A.
obj->interfaceFunc();
}
void someFunc(T obj)
{
// T must implement this function in order to be usable within class A.
obj.interfaceFunc();
}
};
If you want to do it that way, then you need to take a reference instead of a pointer in the first partial specialization:
template<typename T>
class A
{
public:
// Lots of functions...
virtual void virtualHelperFunction(T* obj)
{
// We should never be here in the base class.
assert(false);
}
void someFunc(T obj)
{
// Call the virtual function.
virtualHelperFunction(&obj);
}
};
// Partial specialisation 1
template<typename T>
class B : public A<T>
{
public:
// ...
virtual void virtualHelperFunction(T& obj)
{
obj.interfaceFunc();
}
};
// Partial specialisation 2
template<typename T*>
class B : public A<T*>
{
public:
// ...
virtual void virtualHelperFunction(T* obj)
{
obj->interfaceFunc();
}
};
Your code doesn't compile. template<typename T*> is illegal and you do not have any partial specializations as you claim.
This works:
template<typename T>
class A
{
public:
// Lots of functions...
virtual void virtualHelperFunction(T* obj)
{
// We should never be here in the base class.
assert(false);
}
void someFunc(T obj)
{
// Call the virtual function.
virtualHelperFunction(&obj);
}
};
// Unspecialized template
template<typename T>
class B : public A<T>
{
public:
// ...
virtual void virtualHelperFunction(T* obj)
{
obj->interfaceFunc();
}
};
// Partial specialisation
template<typename T>
class B<T*> : public A<T*>
{
public:
// ...
virtual void virtualHelperFunction(T** obj)
{
(*obj)->interfaceFunc();
}
};
int main() {
B<SomeObject> instance1;
instance1.someFunc(SomeObject());
B<SomeObject*> instance2;
SomeObject x;
instance2.someFunc(&x);
}
here's my problem.
I have a template abstract class RandomVariable with pure virtual function operator()()
template<T>
class RandomVariable<T> {
public:
virtual T operator()() = 0;
/* other stuff */
protected:
T value;
}
I also have a template abstract class Process with pure virtual function operator()()
template<T>
class Process<T> {
public:
typedef std::pair<double, T> state;
typedef std::list<state> result_type;
virtual result_type operator()() = 0;
/* other stuff */
protected:
result_type trajectory;
}
I can easily write a method returning generating a path and returning the last value of my trajectory.
T GenerateTerminalValue() {
this->operator()();
return value.back().second;
};
But it would be much better if, instead of returning type T my function actually returned a functor (ideally derived from RandomVariable) with overloaded operator() generating a path and returning the last value of the trajectory. My best try only led to a Segmentation Fault.
What would be a good way to do this? Thanks.
What about using std::function?
#include <functional>
template<typename T>
class MyClass {
public:
std::function<T()> GenerateTerminalValueFunc() {
return [this]() {
this->operator()();
return value.back().second;
};
}
...
};
Update: If you want to derive from RandomVariable you could try something like this:
#include <memory>
template<typename T>
class TerminalValueOp : public RandomVariable<T>
{
private:
MyClass<T>* obj_;
public:
TerminalValueOp(MyClass<T>* obj) : obj_(obj) {}
T operator()() {
obj->operator()();
return obj->value.back().second;
}
...
};
template<typename T>
class MyClass {
public:
std::shared_ptr<RandomVariable<T>> GenerateTerminalValueOp() {
return std::make_shared<TerminalValueOp<T>>(this);
}
...
};