How do I create a metafunction that takes any kind of function pointer? In the code below, how do I get rid of "decltype(&f)" ?
template <class FuncType, FuncType functionPointer>
void runFunc()
{
functionPointer();
}
runFunc<decltype(&f),f>();
I don't want to have to specify the type of f seperately; the information is already there in f. I'd prefer not to resort to defines to solve this.
This is basically the templated function type idiom applied to meta-programming; I don't want to know the type of f, but whatever I get in apparently allows me to call operator() on it.
Stuff I've tried:
Different order for the template parameters; since later parameters seem to be guessable when you have a function; not possible because then you would need to forward declare FuncType, in order to have it as the type for functionPointer
Switching it around so that you specify returntype and parameters and give a function pointer of that type; cannot instantiate a template with variable template arguments in the middle; that looks like below:
template <class ReturnType, class ... ArgTypes, ReturnType (*functionPointer)(ArgTypes...)>
void runFunc()
{
functionPointer();
}
runFunc<void, int, f>(); // error; invalid template argument for 'ArgTypes', type expected
There's a bit more context here on github: https://github.com/TamaHobbit/FuncTest/blob/master/FuncTest/FuncTest.cpp
You can use this:
template <typename FuncType>
void runFunc(FuncType functionPointer )
{
functionPointer();
}
runFunc(f);
Right now there is unfortunately no good way of doing this.
The standard committee has, however, accepted a proposal that makes this valid code:
template <auto functionPointer>
void runFunc() {
functionPointer();
}
Compiler support should be coming soon.
Related
Maybe it's flu, or I'm just plain stupid, but I can't understand a part of this Crow framework code. My inner C++ parser fails.
template <typename MW>
struct check_before_handle_arity_3_const
{
template <typename T,
//this line
void (T::*)(int, typename MW::context&) const = &T::before_handle
>
struct get
{ };
};
I know it's a template parameter inside template declaration. It looks like maybe some lambda or function pointer type parameter... but, I'm not sure.
Can someone explain this line?
Update:
Exploring depths of newly obtained knowledge - after the answer was given - led me to this excerpt from a great book:
A template can accept a pointer to a function as a nontype template
parameter. (Most often in this book, nontype template parameters are
integral values.) [...] Using a pointer to a function as a nontype
template argument means that we no longer need to store it in the map.
This essential aspect needs thorough understanding. The reason we
don't need to store the pointer to a function is that the compiler has
static knowledge about it. Thus, the compiler can hardcode the
function address in the trampoline code.
So, now I know one of the reasons to use this technique.
void (T::*)(int, typename MW::context&) const is a non-type template parameter.
It is a pointer to a member function of T.
With the use of = &T::before_handle, its default value is set to &T::before_handle.
The reason I used this technique is to support 2 kinds of handler format:
https://github.com/ipkn/crow/blob/master/include/middleware.h#L17
check_before_handle_arity_3_const is used here:
template <typename T>
struct is_before_handle_arity_3_impl
{
template <typename C>
static std::true_type f(typename check_before_handle_arity_3_const<T>::template get<C>*);
template <typename C>
static std::true_type f(typename check_before_handle_arity_3<T>::template get<C>*);
template <typename C>
static std::false_type f(...);
public:
static const bool value = decltype(f<T>(nullptr))::value;
};
With SFINAE, is_before_handle_arity_3_impl<T>::value is determined whether we can call the handler with 3 arguments or not. By using std::enable_if, Crow can call the proper handler:
https://github.com/ipkn/crow/blob/master/include/http_connection.h#L110
I'm writing a template function that receives a std::function object (Generated by calling std::bind with the proper arguments).
Within this function, I would like to determine the return type of this function object. Is is possible?
As a matter of fact, I want the template function to return the same type. Can you think of an elegant, standard based, way of achieving this goal?
Something like:
template <typename T>
T::return_type functionObjWrapper(T functionObject) {
// ...
return functionObject();
}
Thanks
You can do it using decltype and trailing return type:
template <typename T>
auto functionObjWrapper(T functionObject) -> decltype(functionObject()) {
// ...
return functionObject();
}
You're looking for std::function<F>::result_type
I.e.
template <typename F>
typename std::function<F>::result_type
functionObjWrapper(std::function<F> functionObject) {
// ...
return functionObject();
}
The typename before std::function<F>::result_type is needed because that's a dependent type name.
template <class F>
std::result_of_t<F&()> functionObjWrapper(F functionObject) {
// ...
return functionObject();
}
std::result_of takes a type-expression that "looks like a function call". It then tells you what would happen if you did a function call with that callable type, and those arguments.
If you lack C++14, replace std::result_of_t<?> with typename std::result_of<?>::type, or write your own:
template<class Sig>
using result_of_t=typename std::result_of<Sig>::type;
In many C++11 implementations, result_of is even SFINAE friendly.
I do F&() instead of F() because we are going to use a non-const lvalue of type F to do the call. If your last line was std::move(functionObject)() or std::forward<F>(functionObject)(), you would do result_of_t<F()>.
My template-fu is rather weak. I have this code:
template<typename T>
void Foo(void(*func)(T*)) { }
void Callback(int* data) { }
int Test()
{
Foo(Callback);
}
...but I'd like something more readable than C's nasty function pointer syntax of void(*func)(T*).
Someone on my team suggested this:
template<typename T>
struct Types
{
typedef void Func(T*);
};
template<typename T>
void Foo2(typename Types<T>::Func* func) {}
void Test2()
{
Foo2(Callback); // could not deduce template argument for 'T'
Foo2<int>(Callback); // ok
}
(I'm still debating whether this is actually more readable, but that's a separate issue.)
How can I help the compiler figure out what T is without needing to explicitly specify it in the caller?
You can extract T from the function type using a traits class.
template<class F>
struct CallbackTraits;
template<class T>
struct CallbackTraits<void(*)(T)>
{
typedef T ArgumentType;
};
Your example can be modified like this:
template<typename F>
void Foo(F func)
{
typedef typename CallbackTraits<F>::ArgumentType T;
}
void Callback(int* data) { }
int Test()
{
Foo(Callback);
}
This technique is used in the boost type-traits library:
http://www.boost.org/doc/libs/1_57_0/libs/type_traits/doc/html/boost_typetraits/reference/function_traits.html
This blog post goes into a bit more detail about the implementation of the technique:
https://functionalcpp.wordpress.com/2013/08/05/function-traits/
Unfortunately this approach hides the information in the signature of Foo about the constraints on the argument passed in. In the above example the argument must be a function of type void(T*).
This alternative syntax does the same as the original example while being slightly more readable:
template<typename T>
void Foo(void func(T*)) { }
Another alternative syntax that may be more readable can be achieved using c++11's alias templates as follows:
template<typename T>
using Identity = T;
template<typename T>
void Foo(Identity<void(T*)> func) { }
Unforunately the latest MSVC fails to compile this, reporting an internal compiler error.
You won't be able to deduce the type based on a nested name: there is no reason why different instantiations of the outer type won't define an identical inner type. You could use a using alias, though:
template <typename T>
using Function = auto (*)(T*) -> void;
template <typename T>
void Foo(Function<T>) {
}
Personally, I would recommend against using any of that, however: in practice it seems much more advisable to actually take a function object which later allows using object with suitable function call operators to be used. For callbacks it is quite common that you'll need to pass in some auxiliary data. That is, you would either use an unconstrained template or one which takes a type-erased type, depending on what you want to do exactly:
template <typename Fun>
void Unconstrained(Fun fun) {
}
template <typename T>
void TypeErased(std::function<void(T*)> fun) {
}
The unconstrained version has the advantage that it can potentially inline the function call but it has the disadvantage that every function object type creates a new instantiation and that the argument types are likely to vary. The type-erased version effectively has to do something like a virtual function call but there is just one instantiation of the function template (per argument type T, of course).
Admittedly, the type-erased version's type won't be deduced from a function pointer (or any other argument which isn't a std::function<void(X*)>), i.e., you may want to have a forwarding function
template <typename T>
void TypeErased(Function<T> fun) {
TypeErased(std::function<void(T)>(fun));
}
In C++98 and C++03 template argument deduction only works with functions (and methods).
I don't think the picture changed in the more recent standards.
The std::function class is templated in such a way that when we want it to wrap a function like the following:
void printInt(int integer)
{
std::cout << int << '\n';
}
We use a std::function<void(int)>. Until recently I thought this was an odd nuance of the class, but a class I found while searching for delegate implementation in C++ uses a similar syntax.
What exactly is void(int), and what do we call it in technical terms? It seems to be the standard way of saying "a function that takes an int, and returns void" in codespeak, but my gut instinct says that's horribly oversimplified.
Secondly, I've noticed that when I see templates using this syntax they use variadic templates to allow multiple function signatures to be matched. From the link above:
template <typename T> class delegate;
template<class R, class ...A>
class delegate<R (A...)>
{
...
What is the reason for declaring the function as such instead of simply using the following:
template<class R, class ...A>
class delegate
{
...
The template parameter to std::function<Signature> is simply the type of a function, i.e., its signature. It uses the same notation as any function declaration except that it isn't named and the name is left out. You may have come across function pointers which use the same notation but the function signature is used for a pointer.
The reason std::function<Signature> (and apparently delegate<Signature>) are implemented using template specialization is to yield a nicer type:
template <typename T> class function;
template <typename R, typename... Args>
class function {
public:
R operator()(Args...);
// ...
};
template <typename R, typename... Args>
class other {
public:
R operator()(Args...);
// ...
};
int main() {
function<int(double, char)> f;
other<int, double, char> o;
}
Since the primary template for function<T> takes one type as argument, using the specialization the argument can be a normal function type. On the other hand, the same isn't done for other<T...> which, thus, gets a list of types.
It is worth nothing that std::function<T> objects can be passed around quite easily without any need to deal with many template arguments: since the function's signature is just a type, this class template takes just one template argument.
Recently I was trying to create flexible observer pattern implementation which hides boost::signal. I almost succeeded.
I have a Observer class which has to have an update method matching signature provided by template parameter.
Example of use:
Observable<void(float, float)> observable;
Observer<void(float, float)> observer;
observable.attach(&observer);
observable.notify(Observable::Arguments(10.0f, 1.0f)); // invokes observer->update(10.0f, 1.0f);
Everything works just fine if observer does not have overloaded update method. In that case boost::bind can not deduce correct method to use. Unfortunately I can't use explicit casting because I don't know update arguments (this information is in FunctionSignature).
Following method causes troubles:
class Observable <typename FunctionSignature>
{
...
template <class DerivedObserverClass>
void attach(DerivedObserverClass* observer)
{
STATIC_ASSERT((boost::is_base_of<ObserverType, DerivedObserverClass>::value));
ConnectionsMap::iterator it = connections.find(observer);
if (it == connections.end() || !it->second.connected()) {
// i would like to do something like
// boost::function<FunctionSignature> f;
// f = boost::bind(&static_cast<FunctionSignature>DerivedObserverClass::update, observer, _1);
// singnalSlot is defined as boost::signal<FunctionSignature>
// this works as long, as Derived class doesn't have overloaded update method
connections[observer] = signalSlot.connect(boost::bind(&DerivedClass::update, observer, _1));
} else {
throw std::invalid_argument("Observer already attached.");
}
}
I think that boost::function could help to solve this problem. I don't know how to bind it with correct member method using only template signature.
Is it even possible?
No, boost::function won't help you either. 13.4.3 says
Nonstatic member functions match targets of type
“pointer-to-member-function;” the function type of the pointer to
member is used to select the member function from the set of
overloaded member functions.
This means you cannot take an address of overloaded member function, pass it to any kind of function object (templated or not, boost or std or whatever), and hope the overloading will resolve itself. You need a genuine honest pointer-to-member-function type at the left-hand side of the assignment.
You will have to convert your FunctionSignature to a pointer-to-member-function type somehow. Here's some old-fashioned template magic that does what you need, for a limited number of function arguments. c++0x might have a better, more general solution.
template <typename C, typename F>
struct tomemfun;
template <typename C, typename res>
struct tomemfun<C, res()>
{
typedef res (C::*memfun_t)();
};
template <typename C, typename res, typename arg1>
struct tomemfun<C, res(arg1)>
{
typedef res (C::*memfun_t)(arg1);
};
template <typename C, typename res, typename arg1, typename arg2>
struct tomemfun<C, res(arg1, arg2)>
{
typedef res (C::*memfun_t)(arg1, arg2);
};
// repeat with more arguments as needed
Now you can use
tomemfun<DerivedClass, FunctionSignature>::memfun_t update = &DerivedClass::update;
and it will resolve to the right overloaded function.
boost might already have such a conversion template, but I couldn't find it.