Template function pointer parameter vs constructor argument - c++

I have a dilemma about how I should pass a function pointer that will be used extensively by a class throughout the object lifetime. I have thought of 2 solutions:
Passing the function pointer to the constructor and storing it inside the class:
using Func = int(*)(int);
class A
{
public:
explicit A(int n, Func f)
: _f(f), _n(n)
{}
int Process()
{
return f(n);
}
private:
Func _f;
int _n;
};
Or using a template parameter:
using Func = int(*)(int);
template<Func f>
class A
{
public:
explicit A(int n)
: _n(n)
{}
int Process()
{
return f(n);
}
private:
int _n;
};
I think the template solution is more elegant but I am not really sure if it is the best solution.
And as a subsidiary question in the template solution, if only the Process method is using the template parameter can I still put the constructor in a source file and keep the Process method in the header file?

Passing f as a template parameter will result in a separate instantiation of the template for each different value of f. If the code size implications of this worry you, don't use a template. If not, and execution time is of paramount importance, then do.
An example of where using a template parameter can speed up execution is std::sort. If you pass a conventional function pointer for the comparison function (as in the C-style qsort), then the time to call it often accounts for a large part of the time to perform the sort. OTOH, std::sort can inline simple comparison functions, which is faster.

With minor exceptions, templates must be implemented in header files. This is a problem if you have and API and want to hide how a proprietary piece of code is implemented, for instance, as anyone could simply open the header and look at it.
It also could increase compile time, as the template class needs to get created by the compiler at compile time, vs. getting linked in by the linker.
If neither of these problems bother you, then templates are probably a good way to go here. For one, as you say, it is more eloquent and for another they are quite flexible. If you wake up tomorrow and want to use a different type of function pointer, you are quite free to do so.
Of course, the final decision is up to you, but hopefully now you know some of the pros and cons of each.
Edit: Somehow I missed the last part of your question.
So, any templated part of your code must go in the header. Since your whole class is templated, then you can't put it in a source file.
What you can do instead is make only function that accepts it as a parameter itself templated:
class A
{
public:
explicit A(int n); // an go in C++ now
template<Func f>
int Process()
{
return f(n);
}
// ...
};
However, doing it that way will allow Process to accept any function pointer independent of the class. That is, A is no longer bound to a specific f, but rather an individual call to Process is bound to an f. That may not be what you want. Instead, it may be better to do option 1 than my suggested option 3. But again, that's up to you.

Related

Type erasure and variadic templated member function

The example below is a minimal, maybe not so good example of a well known idiom.
It compiles and it is so ugly in order to be able to maintain it minimal, because the question is not about the idiom itself.
struct Foo {
virtual void fn() = 0;
};
template<class T>
struct Bar: public Foo {
void fn() override {
T{}.fn();
}
};
struct S {
void fn() { }
};
int main() {
Foo *foo = new Bar<S>{};
foo->fn();
}
What I'm struggling with since an hour ago is how to change it (or even, if there exists an alternative idiom) to introduce a variadic template member method.
Obviously, I cannot modify the fn function of the Foo class, because it's a virtual one and virtual specifier doesn't goes along with templates. The same is valid for the fn specification of Bar, because it has to override somehow the one in the base class.
Note.
For I strongly suspect that this question could be one of the greatest XYProblem ever seen, I'd like also to give a brief description of the actual problem.
I have a class that exposes two templated member methods:
the first one accepts a template class T that is not used immediately, instead it should be stored somehow in order to be used later.
the second one accepts a variadic number of arguments (it is actually a variadic templated member function) and those arguments should be perfectly forwarded to a newly created instance of T.
Well, the problem is far more complex, but this is a good approximation of it and should give you an idea of what's the goal.
Edit
I guess that it is somehow similar to higher order functions.
I mean, what would solve the problem is indeed a templated function to which to bind the first argument, but as far as I know this is impossible as well as any other approach I've explored so far.
Any viable solution that expresses the same concept?
What I mentioned in the comments is the following approach:
template<typename T> class Factory {
public:
template<typename ...Args>
auto construct(Args && ...args)
{
return T(std::forward<Args>(args)...);
}
};
So now, your first exposed class method will be something like this:
template<typename T>
auto getFactory() {
return Factory<T>();
}
So:
auto factory=object.getFactory<someClass>();
// Then later:
factory.construct(std::string("Foo"), bar()); // And so on...
Instead of construct() you could use operator() too, so the second part of this becomes, simply:
factory(std::string("Foo"), bar()); // And so on...
As I mentioned, this is not really type erasure. You can't use type erasure here.
Having given this a few minutes' more thought, the reason that type erasure cannot be used here is because a given instance of type erasure must be "self contained", or atomic, and what you need to do is to break atomic type erasure into two parts, or two class methods, in your case.
That won't work. Type erasure, by definition, takes a type and "erases" it. Once your first function type-erases its class method template parameter, what you end up with is an opaque, type-erased object of some kind. What was type-erased is no longer available, to the outside world. But you still haven't type-erased your constructor parameters, which occurs somewhere else.
You can type-erase the template class, and the constructor parameters together. You can't type-erase the template class, and the constructor parameters, separately and then somehow type-erase the result again.
The simple factory-based approach, like the one I've outlined, would be the closest you can get to results that are similar to type erasure, if both halfs of your desired type-erasure appear in the same scope, so you can actually avoid type-erasure, and instead rely on compiler-generated bloat.
I also agree that you cannot do exactly what you want here. I will post what I think the closest option is (at least a close option that is different from SamVarshavchik's answer).
I don't expect this answer to solve your problem exactly, but hopefully it will give you some ideas.
struct Delay // I have no idea what to call this
{
template <class T>
void SetT()
{
function_ = [](boost::any params){return T(params);}
}
template <class ... Args>
boost::any GetT(Args ... args)
{
return function_(std::make_tuple(args...));
}
private:
std::function<boost::any(boost::any)> function_;
};
The obvious limitation of this is that anyone calling GetT will somehow have to know what T was already, though you can query the boost::any object for the type_info of its class if that helps. The other limitation here is that you have to pass in T's that take a boost::any object and know what to do with it. If you cannot have T do that, then you can change SetT (or create a new member function) like this:
template <class F>
SetTFactory(F f)
{
function_ = f;
}
and then use it like:
Delay d;
d.SetTFactory([](boost::any s){return std::string(boost::any_cast<const char*>(s));});
auto s = d.GetT("Message");
assert(s.type() == typeid(std::string));
This of course introduces a whole new set of difficulties to deal with, so I don't know how viable this solution will be for you. I think regardless of anything else, you're going to have to rethink your design quite a bit.

Convert Switch to Non-virtual Polymorphism

I currently have a C++ interface
void foo() ...
and lots of implementions
void A::foo();
void B::foo();
Currently foo is defined as follows
struct Wrapper
{
void foo()
{
if(state == STATE_A) a.foo();
else if(state == STATE_B) b.foo();
}
union {
A a;
B b;
};
State state;
}
//....
Wrapper a(STATE_A, existingA);
Wrapper b(STATE_B, existingB);
a.foo(); b.foo();
Is there a cleaner way to do this? I have multiple foo() like functions and multiple A/B like classes. It's getting tedious/error prone to write all the cases.
Note that I cannot use virtual functions (this runs inside a N^5 loop... with 10 million+ executions / second). I want the compiler to inline this, hard.
I have thought of collecting A's, B's, etc together and computing them in a data oriented fashion, but unfortunately I can't do that (due to algorithm concerns)
I want the compiler to inline this, hard.
That's not going to happen.
You're using runtime polymorphism. By definition, the compiler cannot know which function will be called at call time. You are going to pay for virtual dispatch, whether you do it manually or let the compiler do it.
The absolute most inlining you will get is in the calls to the member functions. It still has to do a conditional branch based on a memory access (fetching the "type") to get to the "inline" part. And every new "state" you add will add another condition to that branch. At best, this will become a state table... which is no different from just a virtual function pointer: it fetches from a memory address, and uses that to branch to a particular piece of code.
Just like a vtable pointer, only you wasted your time implementing something the compiler could do for you.
I strongly advise you to profile this instead of simply assuming that your hand-written method can beat the compiler.
If you've decided to abandon language-level polymorphism, then you should use a boost.variant and appropriate visitors instead. Your code would look like this:
typedef boost::variant<A, B> Wrapper;
struct FooVisitor : public boost::static_visitor<>
{
template <typename T> void operator()(T &t) {t.foo()};
};
You will have to make a FooVisitor for every function you want to call. To call it, you do this:
Wrapper a = existingA;
boost::apply_visitor(FooVisitor(), a);
Obviously, you can wrap that in a simple function:
void CallFoo(Wrapper &a) {boost::apply_visitor(FooVisitor(), a);}
Indeed, you can make a whole template family of these:
template<typename Visitor>
void Call(Wrapper &a) {boost::apply_visitor(Visitor(), a);}
Note that parameter passing is not allowed (you have to store the parameters in the visitor itself), but they can have return values (you have to put the return type in the boost::static_visitor<Typename_Here> declaration of your visitor).
Also note that boost::variant objects have value semantics, so copies will copy the internal object. You can also use the boost::get() syntax to get the actual type, but I would not suggest it unless you really need it. Just use visitors.
You have two choices. You can do the function selection at compile time, or you can do it at run time. If it's run time you're not going to do better than the existing virtual mechanism. If it's compile time you need different code for each type you're going to use, but you can use templates to automate the process.
template<typename T>
struct Wrapper
{
void foo()
{
t.foo();
}
T t;
};
Of course this example is highly abstracted and I can't see any difference between using the Wrapper class and the template type directly. You'll have to flesh out your example a little more to get a better answer.

Storing C++ templated objects as same type

I have a class that is a core component of a performance sensitive code path, so I am trying to optimize it as much as possible. The class used to be:
class Widget
{
Widget(int n) : N(n) {}
.... member functions that use the constant value N ....
const int N; // just initialized, will never change
}
The arguments to the constructor are known at compile time, so I have changed this class to a template, so that N can be compiled into the functions:
template<int N>
class Widget
{
.... member functions that use N ....
}
I have another class with a method:
Widget & GetWidget(int index);
However, after templating Widget, each widget has a different type so I cannot define the function like this anymore. I considered different inheritance options, but I'm not sure that the performance gain from the template would outweigh the cost of inherited function invocations.
SO, my question is this:
I am pretty sure I want the best of both worlds (compile-time / run-time), and it may not be possible. But, is there a way to gain the performance of knowing N at compile time, but still being able to return Widgets as the same type?
Thanks!
The issue here is that if you store the widgets as the same type, then the code that retrieves the widgets from that store (by calling GetWidget) doesn't know N at compile time[*]. The code that calls the constructor knows N, but the code that uses the object has to cope with multiple possibilities.
Since the performance hit (if any) is likely to be in the code that uses the widgets, rather than the code that creates them, you can't avoid doing something in the critical code that depends on runtime information.
It may be that a virtual call to a function implemented in your class template, is faster than a non-virtual call to a function that uses N without knowing the value:
class Widget {
public:
virtual ~Widget() {}
virtual void function() = 0;
};
template <int N>
class WidgetImpl : public Widget {
public:
virtual void function() { use N; }
};
The optimizer can probably do its best job when N is known, since it can optimally unroll loops, transform arithmetic, and so on. But with the virtual call you're looking at one big disadvantage to start with, which is that none of the calls can be inlined (and I would guess a virtual call is less likely to be predicted than a non-virtual call when not inlined). The gain from inlining with unknown N could be more than the gain of knowing N, or it could be less. Try them both and see.
For a more far-fetched effort, if there are a reasonably small number of common cases you might even see an improvement by implementing your critical widget function as something like:
switch(n) {
case 1: /* do something using 1 */; break;
case 2: /* do the same thing using 2 */; break;
default: /* do the same thing using n */; break;
};
"do something" for all cases but the default could be a call to a function templated on the constant, then the default is the same code with a function parameter instead of a template parameter. Or it could all be calls to the same function (with a function parameter), but relying on the compiler to inline the call before optimization in the cases where the parameter is constant, for the same result as if it was templated.
Not massively maintainable, and it's usually a bad idea to second-guess the optimizer like this, but maybe you know what the common cases are, and the compiler doesn't.
[*] If the calling code does know the value of N at compile time, then you could replace GetWidget with a function template like this:
template <int N>
Widget<N> &getWidget(int index) {
return static_cast<Widget<N> &>(whatever you have already);
}
But I assume the caller doesn't know, because if it did then you probably wouldn't be asking...
You need to declare a non-templated type from which the templated type inherits, and then store the widgets as pointers to the non-templated base class. That is the only (type-safe) way to accomplish what you are looking for.
However, it is probably cleaner to keep the non-templated version. Have you profiled your code to see that the loops on the runtime-configured version are actually a bottleneck?
I guess the following is not an option?
template <int N>
Widget<N> & GetWidget();
Anyway, as soon as you’re managing several widget types together you cannot make them templated anymore since you can’t store objects of different type in one container.
The non-templated base class proposed by Michael is a solution but since it will incur virtual function call costs I’m guessing that making the class templated hasn’t got any benefits.
If your types are finite and known, you could use a boost::variant as an argument to your constructor.
The variant class template is a safe,
generic, stack-based discriminated
union container, offering a simple
solution for manipulating an object
from a heterogeneous set of types in a
uniform manner. Whereas standard
containers such as std::vector may be
thought of as "multi-value, single
type," variant is "multi-type, single
value."
here is some pseudo code
boost::variant< int, double, std::string > variant;
const variant foo( 1 );
const variant bar( 3.14 );
const variant baz( "hello world" );
const Widget foo_widget( foo );
const Widget bar_widget( bar );
const Widget baz_widget( baz );
Alternatively, you could use a boost::any for more flexibility.
You could write a templated GetWidget function. That would require you to know the type when you call GetWidget:
w = GetWidget<Box>(index);

Virtual Methods or Function Pointers

When implementing polymorphic behavior in C++ one can either use a pure virtual method or one can use function pointers (or functors). For example an asynchronous callback can be implemented by:
Approach 1
class Callback
{
public:
Callback();
~Callback();
void go();
protected:
virtual void doGo() = 0;
};
//Constructor and Destructor
void Callback::go()
{
doGo();
}
So to use the callback here, you would need to override the doGo() method to call whatever function you want
Approach 2
typedef void (CallbackFunction*)(void*)
class Callback
{
public:
Callback(CallbackFunction* func, void* param);
~Callback();
void go();
private:
CallbackFunction* iFunc;
void* iParam;
};
Callback::Callback(CallbackFunction* func, void* param) :
iFunc(func),
iParam(param)
{}
//Destructor
void go()
{
(*iFunc)(iParam);
}
To use the callback method here you will need to create a function pointer to be called by the Callback object.
Approach 3
[This was added to the question by me (Andreas); it wasn't written by the original poster]
template <typename T>
class Callback
{
public:
Callback() {}
~Callback() {}
void go() {
T t; t();
}
};
class CallbackTest
{
public:
void operator()() { cout << "Test"; }
};
int main()
{
Callback<CallbackTest> test;
test.go();
}
What are the advantages and disadvantages of each implementation?
Approach 1 (Virtual Function)
"+" The "correct way to do it in C++
"-" A new class must be created per callback
"-" Performance-wise an additional dereference through VF-Table compared to Function Pointer. Two indirect references compared to Functor solution.
Approach 2 (Class with Function Pointer)
"+" Can wrap a C-style function for C++ Callback Class
"+" Callback function can be changed after callback object is created
"-" Requires an indirect call. May be slower than functor method for callbacks that can be statically computed at compile-time.
Approach 3 (Class calling T functor)
"+" Possibly the fastest way to do it. No indirect call overhead and may be inlined completely.
"-" Requires an additional Functor class to be defined.
"-" Requires that callback is statically declared at compile-time.
FWIW, Function Pointers are not the same as Functors. Functors (in C++) are classes that are used to provide a function call which is typically operator().
Here is an example functor as well as a template function which utilizes a functor argument:
class TFunctor
{
public:
void operator()(const char *charstring)
{
printf(charstring);
}
};
template<class T> void CallFunctor(T& functor_arg,const char *charstring)
{
functor_arg(charstring);
};
int main()
{
TFunctor foo;
CallFunctor(foo,"hello world\n");
}
From a performance perspective, Virtual functions and Function Pointers both result in an indirect function call (i.e. through a register) although virtual functions require an additional load of the VFTABLE pointer prior to loading the function pointer. Using Functors (with a non-virtual call) as a callback are the highest performing method to use a parameter to template functions because they can be inlined and even if not inlined, do not generate an indirect call.
Approach 1
Easier to read and understand
Less possibility of errors (iFunc cannot be NULL, you're not using a void *iParam, etc
C++ programmers will tell you that this is the "right" way to do it in C++
Approach 2
Slightly less typing to do
VERY slightly faster (calling a virtual method has some overhead, usually the same of two simple arithmetic operations.. So it most likely won't matter)
That's how you would do it in C
Approach 3
Probably the best way to do it when possible. It will have the best performance, it will be type safe, and it's easy to understand (it's the method used by the STL).
The primary problem with Approach 2 is that it simply doesn't scale. Consider the equivalent for 100 functions:
class MahClass {
// 100 pointers of various types
public:
MahClass() { // set all 100 pointers }
MahClass(const MahClass& other) {
// copy all 100 function pointers
}
};
The size of MahClass has ballooned, and the time to construct it has also significantly increased. Virtual functions, however, are O(1) increase in the size of the class and the time to construct it- not to mention that you, the user, must write all the callbacks for all the derived classes manually which adjust the pointer to become a pointer to derived, and must specify function pointer types and what a mess. Not to mention the idea that you might forget one, or set it to NULL or something equally stupid but totally going to happen because you're writing 30 classes this way and violating DRY like a parasitic wasp violates a caterpillar.
Approach 3 is only usable when the desired callback is statically knowable.
This leaves Approach 1 as the only usable approach when dynamic method invocation is required.
It's not clear from your example if you're creating a utility class or not. Is you Callback class intended to implement a closure or a more substantial object that you just didn't flesh out?
The first form:
Is easier to read and understand,
Is far easier to extend: try adding methods pause, resume and stop.
Is better at handling encapsulation (presuming doGo is defined in the class).
Is probably a better abstraction, so easier to maintain.
The second form:
Can be used with different methods for doGo, so it's more than just polymorphic.
Could allow (with additional methods) changing the doGo method at run-time, allowing the instances of the object to mutate their functionality after creation.
Ultimately, IMO, the first form is better for all normal cases. The second has some interesting capabilities, though -- but not ones you'll need often.
One major advantage of the first method is it has more type safety. The second method uses a void * for iParam so the compiler will not be able to diagnose type problems.
A minor advantage of the second method is that it would be less work to integrate with C. But if you're code base is only C++, this advantage is moot.
Function pointers are more C-style I would say. Mainly because in order to use them you usually must define a flat function with the same exact signature as your pointer definition.
When I write C++ the only flat function I write is int main(). Everything else is a class object. Out of the two choices I would choose to define an class and override your virtual, but if all you want is to notify some code that some action happened in your class, neither of these choices would be the best solution.
I am unaware of your exact situation but you might want to peruse design patterns
I would suggest the observer pattern. It is what I use when I need to monitor a class or wait for some sort of notification.
For example, let us look at an interface for adding read functionality to a class:
struct Read_Via_Inheritance
{
virtual void read_members(void) = 0;
};
Any time I want to add another source of reading, I have to inherit from the class and add a specific method:
struct Read_Inherited_From_Cin
: public Read_Via_Inheritance
{
void read_members(void)
{
cin >> member;
}
};
If I want to read from a file, database, or USB, this requires 3 more separate classes. The combinations start to be come very ugly with multiple objects and multiple sources.
If I use a functor, which happens to resemble the Visitor design pattern:
struct Reader_Visitor_Interface
{
virtual void read(unsigned int& member) = 0;
virtual void read(std::string& member) = 0;
};
struct Read_Client
{
void read_members(Reader_Interface & reader)
{
reader.read(x);
reader.read(text);
return;
}
unsigned int x;
std::string& text;
};
With the above foundation, objects can read from different sources just by supplying different readers to the read_members method:
struct Read_From_Cin
: Reader_Visitor_Interface
{
void read(unsigned int& value)
{
cin>>value;
}
void read(std::string& value)
{
getline(cin, value);
}
};
I don't have to change any of the object's code (a good thing because it is already working). I can also apply the reader to other objects.
Generally, I use inheritance when I am performing generic programming. For example, if I have a Field class, then I can create Field_Boolean, Field_Text and Field_Integer. In can put pointers to their instances into a vector<Field *> and call it a record. The record can perform generic operations on the fields, and doesn't care or know what kind of a field is processed.
Change to pure virtual, first off. Then inline it. That should negate any method overhead call at all, so long as inlining doesn't fail (and it won't if you force it).
May as well use C, because this is the only real useful major feature of C++ compared to C. You will always call method and it can't be inlined, so it will be less efficient.

Nesting C++ Template Definitions

I'm abusing C++ templates a little and I'm having trouble figuring something out. Let's say I have two types that really should be inherited from a base type, but for speed reasons, I can't afford to have the virtual function overhead (I've benchmarked it, and virtual calls ruin things for me!).
First, here are the two classes I have
template<class DataType> class Class1
{
//Lots of stuff here
}
template<Class DataType> class Class2
{
//The same stuff as in Class1, but implemented differently
}
In a typical oo design, Class1 and Class2 would inherit from IInterface and I could have a function that looks like this
DoStuff(IInterface& MyInterface)
{
}
But I can't do that, so I've done this
template <class C>
DoStuff(C& c)
{
}
I know it's not pretty, as there's nothing (at the compiler level) to enforce that Class1 and Class2 implement the same interface, but for speed reasons, I'm breaking some of the rules.
What I'd love to do is create a call back function on DoStuff, but I can't figure out how to make it work with the templates (especially since there's the hidden in there.
For example this works right now
DoStuff(char* filename)
{
switch (//figure out the type i need to make)
{
case 1: return DoStuff(Class1<int>(filename));
case 2: return DoStuff(Class1<double>(filename));
}
}
template<class DataType>
DoStuff(DataType* pdata)
{
return DoStuff(Class2<DataType>(pdata));
}
template<class C>
DoStuff(C c)
{
c.Print();
}
Now I know you're asking, why use Class1 and Class2? Well the underlying difference between dealing with a file and dealing with memory is so big, that it makes sense to have different classes for the different type of input (rather than just overloading the constructor and having it behave differently for the different inputs). Again, I did benchmark this and it's much faster to have the special cases handled in their own classes rather than having cases/ifs in every function.
So what I'd like to do is hide a lot of this implementation from the junior developers, I don't want them to have to create three different overloaded DoStuffs to handle the different inputs. Ideally, I'd just set up some type of callback with #defines and all they'd need to do is something like create a class called DoStuff and overload the () operator and have the functor do the work.
The trouble I'm having is that the DoStuff function that does the work is only templatized by <class C> but C itself is templatized by <class DataType> and everything I can't figure out how to pass everything around in a generic way. E.g., I cannot use template <class C<DataType>> or template<template< class DataType> class C>. It just won't compile.
Does anyone have a good trick to have a generic call back, either a function or a functor (I don't care), with this nested templated class? Basically I want something where I can write a generic function that doesn't care about the class that's storing the data and have that called by a mostly common function that figures out which class to use.
BigSwitch(CallBack,Inputs)
{
switch(//something)
{
case 1: return CallBack(Class1<Type>(Inputs))
case 2: return CallBack(Class2<Type>(Inputs))
}
}
This way I can write one BigSwitch function and have other people write the CallBack functions.
Any Ideas?
EDIT for clarification for Jalf:
I have two very similar classes, Class1 and Class2 which represent basically the same type of data, however the data store is vastly different. To make it more concrete, I'll use a simple example: Class1 is a simple array and Class2 looks like an array however rather than storing in memory is stores in a file (because it's too big to fit in memory). So I'll call them MemArray and FileArray right now. So let's say I wanted the Sum of the arrays. I can do something like this
template <class ArrayType, class ReturnType>
ReturnType Sum(ArrayType A)
{
ReturnType S=0;
for (int i=A.begin();i<A.end();++i)
{
S+=A[i];
}
return S;
}
But now, I need a way to load real data into the array. If it's a memory-based array, I'd do this
MemArray<DataType> M(pData);
and if it's file-baaed, I'd do this
FileArray<DataType> F(filename);
and both of these calls are valid (because the compiler generates both code paths at compile time)
double MS=Sum<MemArray<DataType>,double>(M);
double FS=Sum<FileArray<DataType>,double>(F);
All of this assumes that I know what the DataType is, but for a file based array, I may not know the data type until I open the file and query the header to know what kind of data is in the array.
double GetSum(char* filename)
{
int DataTypeCode=GetDataTypeCode(filename);
switch (DataTypeCode)
{
case 1: return Sum<FileArray<int>,double>(FileArray<int>(filename));
case 2: return Sum<FileArray<double>,double>(FileArray<double>(filename));
}
}
template <class DataType>
double GetSum(DataType* pData)
{
return Sum<MemArray<DataType>,double>(MemArray<DataType>(pData));
}
All of this works, but it requires writing two overloaded GetX functions and a X function for everything that I'd want to do. the GetX functions are basically the same code everytime except for the X that it calls. So I'd love to be able to write something like
double GetX(CallBackType X, char* filename)
{
int DataTypeCode=GetDataTypeCode(filename);
switch (DataTypeCode)
{
case 1: return X<FileArray<int>,double>(FileArray<int>(filename));
case 2: return X<FileArray<double>,double>(FileArray<double>(filename));
}
}
template <class DataType>
double GetX(CallBackType, DataType* pData)
{
return X<MemArray<DataType>,double>(MemArray<DataType>(pData));
}
so that I could call
GetX(Sum,filename)
then later when someone else wants to add a new function, all they need to do is write the function and call
GetX(NewFunction,filename)
I'm just looking for a way to write my overloaded GetX functions and my X functions so that I can abstract way the input/storage from the actual algorithms. Normally, this isn't a hard problem, it's just that I'm having trouble because the X function contains a template argument that itself is templated. The template<class ArrayType> also has an implicit ArrayType<DataType> hidden in there. The compiler is unhappy about that.
Focusing on the initial part of your question (why you're not just using inheritance):
A common way to do compile-time polymorphism and give access to the derived class' members through the base class is through the CRTP pattern.
template <typename T>
class IInterface {
void DoStuff() {
void static_cast<T*>(this)->DoStuff()
}
};
class Class1 : IInterface<Class1> {
void DoStuff(){...}
}
Would that solve your problem?
Edit:
By the way, I'm glad I could help, but next time please try to structure your question a bit more.
I really had no clue what you were asking, so this was just a stab in the dark, based on the first 3 lines of your question. ;)
You never really explain what you're trying to achieve, only what your non-functioning workaround looks like. Start out stating the problem, since that's what we really need to know. Then you can provide details about your current workarounds. And when posting code, add some context. Where are DoStuff() called from, and why would junior developers need to define them? (You've already done that, haven't you?)
What would said junior developers be doing with this code in the first place?
And it's confusing that you provide the specific cases (1 and 2), but not the switch statement itself (//something)
You'll get a lot more (and better and faster) answers next time if you try to make it easy for the person answering. :)
As to your question about a "generalized callback" you can use a boost::function but that essentially uses virtual functions under the covers (it may not - but at least a similar concept) so the performance difference you are looking for won't be there (in fact boost::function will probably be slower because of heap allocation).