Actually I mentioned I was using C++0x (at least parts of it) in the OP, but no worries if you missed it. And ya if I wanted run-time linkage I could use std::function, or boost::function, or one of many other options.
After doing more reading, I'm pretty sure what I'm looking for can't be done. But I'll try to explain it in a bit more detail.
Many times I want to wrap a function in another function. Either to adjust parameters, modify data, ensure something was called, ect... Doing this at run-time is easy, but it also has overhead. For example, imagine you have something like this:
float FuncA (int i) { /* do stuff and return something */ }
float FuncB (int i) { return FuncA(i+1); }
Its a trivial example granted, but wrapping a function to add/adjust functionality happens all the time. Most compilers (GCC, intel, MS) will inline the call to FuncA in FuncB (with the appropriate compiler optimizations turned on, even without the inline keyword).
To do the equivalent with say boost::function (and likewise std::function):
float FuncB (const boost::function<float (int)>& f, int i) { return f(i+1); }
works pretty much the same, but won't necessarily be inlined (haven't tested it out, but would be highly unlikely that it could inline it... I probably should test that sometime). Same problem with a function pointer:
float FuncB (float (*f) (int), int i) { return f(i+1); }
Now you can do:
template <float (&f) (int)> float FuncB (int i) { return f(i+1); }
and this gives you 50% of what I'm looking for. You get a complile-time wrapper with no more overhead than a hand coded wrapper would give you. Which is awesome, but it only works if you know the type of the function you want to wrap.
Say I want the type of a function (to adjust/work with parameters, ect...). I can do:
template <typename T> float FuncB (const T& f, int i) { return f(i+1); }
and now I have T, which is the type of a function, and I can work with it, but its run time, not compile time.
And there-in lies the rub. I can statically link a function OR I can get its type, but I can't do both. What I need is something like:
template <typename T, const T& f> float FuncB (int i) { return f(i+1); }
Except having to supply the function definition is not only tedious, but error prone for complex types. The closest I've been able to get is by wrapping a function in a class (as has been mentioned above) and using decltype like:
template <typename T> void FuncB (int i) {
const auto f = T::FuncA;
typedef decltype(f) TF; // get function type
return f(i+1);
}
This gets me 90% of the way there, problem is I can't get the function type, till the wrapper function is declared, so I can't define things like return values.
There's also:
template <typename T, const T& f> float FuncB (int i) { return f(i+1); }
// elsewhere...
FuncB<decltype(FuncA),FuncA>(5);
Which seems about the best option at this point. A little tedious to write, but it covers the rest of my wish-list.
I just thought I'd post the question as sometimes I make silly mistakes and/or forget obvious things, and I thought maybe in this case there was something I missed or forgot ; )