Promotion of C++ overloaded function pointer to a function object - c++

A C++11 template function which takes a function object argument, such as:
template <typename F, typename T>
auto foo(F f, T x) -> decltype(f(x)) {
return f(x);
}
could take a function such as:
int succ(int i) { return i+1; }
and apply foo to succ and obtain a result of 10:
foo(succ,9);
Overloaded functions don't work, sin, for example, fails:
foo(std::sin,0.5);
in GCC (4.7) with "couldn't deduce template parameter F".
(Providing sin<double> relates only to complex types btw.) Yes, I can struct it right up:
template <typename T>
struct Sin {
T operator()(T x) { return std::sin(x); }
};
with a little:
foo(Sin<double>(),0.5);
My question is, is there an alternative which avoids the need for such a new definition; usable solely at the call site of foo?

For function pointers, you can simply have the user type the signature:
template<class F, class T>
void foo(F f, T x){
f(x);
}
void bar(int){}
void bar(double){}
int main(){
foo<void(int)>(bar, 5);
}
Live example on Ideone.
foo will be void foo(void f(int), int x) after substitution, which is the same as foo(void (*f)(int), int x). This provides a so-called "calling context" which allows the compiler to select the correct overload. Obviously, this only works well if the first template parameter is the function. To work around this limitation, and make it look nicer (imho, atleast), you can provide a simple helper function:
template<class F>
auto get_overload(F f) -> decltype(f) { return f; }
Actually, you can only overload on parameter types, but this you can't cull out the need to have the user type the return type, since this disables the calling context again, as a type would need to be deduced.
Since you most likely (or surely) only want this for function pointers, you can change it to this:
template<class F>
F* get_overload(F* f){ return f; }
It's still completely the same. The only reason why the first version can't just have F as the return type is that F is void(int) if you call it with get_overload<void(int)>(bar), and the standard doesn't allow you to return functions (yes, that's a function type). The function to function pointer transformation (void(int) -> void(*)(int)) part only happens for parameters.
Since for whatever reason #VJovic deleted his answer, I'll just edit this in:
You can actually use a simple lambda instead of the get_overload function. It will be about the same length character wise and much more convenient and clearer. It will also be more efficient, since no (function) pointers are involved and the compiler is perfectly able to inline the call.
foo([](int i){ return bar(i); }, 5);

Related

SFINAE with functions and emulating partial template specialization

I am trying to make a function X that specializes when a member function Y is provided and if the member function Y is not provided the function X uses the global non member function Y to achieve the same effect.
I am currently trying to achieve this with the following code
template <typename Container, typename std::enable_if_t<std::is_same<
decltype(std::declval<Container>().y()),
decltype(std::declval<Container>().y())>::value>* = nullptr>
void do_something(Container&& container) {
return std::forward<Container>().y();
}
template <typename Container, typename std::enable_if_t<!std::is_same<
decltype(std::declval<Container>().y()),
decltype(std::declval<Container>().y())>::value>* = nullptr>
void do_something(Container&& container) {
return y(std::forward<Container>(container);
}
But in the case when the container has both a member function y and the global non member function y also works on it. There is a compile error because for the second version of the function the template argument is ill formed because a member function y is needed.
Any idea how I can go about resolving this issue?
NOTE: This is different from just detecting whether a class has a function of a given signature. Sorry if the question seems to ask that! The accepted answer below should make my intention clearer.
The typical approach is to dispatch to a pair of functions where one is preferred if your condition is met and the other is simply a fallback. The nice thing is you don't even need enable_if, just the trailing decltype:
template <class C>
auto do_something_impl(C&& c, int)
-> decltype(std::forward<C>(c).y())
{
return std::forward<C>(c).y();
}
template <class C>
auto do_something_impl(C&& c, ...)
-> decltype(y(std::forward<C>(c))
{
return y(std::forward<C>(c));
}
And now just pass in 0:
template <class C>
auto do_something(C&& c)
-> decltype(do_something_impl(std::forward<C>(c), 0))
{
return do_something_impl(std::forward<C>(c), 0);
}
The conversion sequence to int is better than the one to ..., so if the type has the member function you want, that overload will be preferred even if both are viable candidates.

Passing template function as argument for normal function

I'm wondering if it's possible to pass a template function (or other) as an argument to a second function (which is not a template).
Asking Google about this only seems to give info about the opposite ( Function passed as template argument )
The only relevant page I could find was http://www.beta.microsoft.com/VisualStudio/feedbackdetail/view/947754/compiler-error-on-passing-template-function-as-an-argument-to-a-function-with-ellipsis
(not very helpful)
I'm expecting something like:
template<class N>void print(A input){cout << input;}
void execute(int input, template<class N>void func(N)){func(input)}
and then later call
execute(1,print);
So, can this be done or would another template have to be defined for execute() ?
Function templates represent an infinite overload set, so unless you have a target type that is compatible with a specialization, deduction of the function type always fails. For example:
template<class T> void f(T);
template<class T> void h(T);
void g() {
h(f); // error: couldn't infer template argument 'T'
h(f<int>); // OK, type is void (*)(int)
h<void(int)>(f); // OK, compatible specialization
}
From above we can see that the validity of the program demands that we specify the template arguments for the function template, when in general it isn't always intuitive to specify them. You can instead make print a functor with a generic overloaded call operator as an extra level of indirection:
struct print {
template<typename T>
void operator()(T&& x) const {
std::cout << x;
}
};
Now you can have execute accept any Callable and invoke it with the input:
template<class T, class Op>
void execute(T&& input, Op&& op) {
std::forward<Op>(op)(std::forward<T>(input));
}
void g() { execute(1, print{}); }
Generic lambdas (C++14) make this a lot more concise:
execute(1, [] (auto&& x) { std::cout << x; });
Execute would need to be a template- there's no way for the compiler to create a single version of execute that would work for any input type. Now if you specified what N is for this specific function- for example if you made the second parameter print- then it should be legal.

Expression SFINAE to overload on type of passed function pointer

In this example a function is passed to an implicitly instantiated function template.
// Function that will be passed as argument
int foo() { return 0; }
// Function template to call passed function
template<typename F>
int call(F f) {
return f();
}
template<typename F, typename A>
int call(F f, A a) {
return f(a);
}
int a = call(foo);
We can break this code by adding an overload for foo().
int foo(int i) { return 0; }
The name "foo" is now ambiguous and the example will no longer compile. This can be made to compile by explicitly providing function pointer type info.
int (*func_takes_void)() = foo;
int a = call(func_takes_void);
int (*func_takes_int)(int) = foo;
int b = call(func_takes_int, 0);
http://coliru.stacked-crooked.com/a/e08caf6a0ac1e6b9
Is it possible to instead deduce the function pointer types? If so, why does my attempt below not work and what is the right way to do this?
If this is not possible, a good answer would explain why.
Attempt thus far
A human can see which foo() is intended in the two calls by inspecting the definitions of call<>() but that info is not available to the compiler for overload resolution. Still, the information is all there, it just needs to be pulled into the function template signature. This may be possible with expression SFINAE.
In pseudo code we want this:
template<IgnoreThis, typename ReturnType>
struct expr_check
{
typedef ReturnType type;
}
template<typename F>
expr_check<expression requiring F have correct signature, result_of<F>::type>::type
call(F f);
Here is that idea worked out in real code.
http://coliru.stacked-crooked.com/a/a3ce828d6cb16c2d
The function template signatures are:
template<typename F>
typename expr_check<sizeof(declval<F>()()), typename func_ptr_result<F>::type>::type
call(F f);
template<typename F, typename A>
typename expr_check<sizeof(declval<F>()(declval<A>())), typename func_ptr_result<F>::type>::type
call(F f, A a);
What I currently have does not compile. From the compiler output you can see that on both attempts to instantiate the function template there is substitution failure on one call<>() overload and the other simply gives an opaque "couldn't deduce template parameter".
(The colirus were compiled as C++03 but C++11 answers are fine.)
My suspicion is that while instantiating call<>(), foo() is not being called and C++ simply does not provide for overload resolution of foo() in this context. It doesn't matter that it can be proven that one foo() overload is the correct one, C++ just doesn't mandate overload resolution here. On the other hand, overload resolution isn't limited to a function being called. A function pointer of appropriate type gets to select overloads of foo().
Related questions
There are a few questions asking about overloading on function pointer type. It looks like this can't be done. I didn't find any questions trying to do this through expression SFINAE.
This seems to be the closest related question.
Is there a way to deduce the value of a function pointer template parameter?
Bonus pedantry
Is "function pointer" the correct phrase to have used in the title? Would "function reference" have been more accurate?
The closest you can get is probably this:
struct sfoo
{
template<typename... args>
void operator() (args&&... a)
{
foo(std::forward<args>(a)...);
}
};
and pass sfoo (or sfoo()) instead of foo around.
That is, create a function object type that encapsulates the entire overload set in the templatized operator().
Then instead of overload resolution over a template argument, which does not exist, you get a template instantiation over the same argument, which is OK.
As has been mentioned before, SFINAE doesn't work because the names of overloaded functions have no definite type in C++, therefore template parameter substitution doesn't even happen at this stage.
However, in your example, the problem is arguably not that you have too many overloads of "foo", but too few overloads of "call". Just provide both the templates with typename F and the ones that expect a function pointer. The compiler will now be able to do the right thing depending on context:
#include <iostream>
// Functions
int foo() { return 0; }
int foo(int) { return 1; }
// Function object
struct Foo
{
int operator()() const { return 2; }
int operator()(int) const { return 3; }
};
// Higher-order functions / templates
template<typename F>
int call(F f) {
return f();
}
int call(int (*f)()) {
return f();
}
template<typename F, typename A>
int call(F f, A a) {
return f(a);
}
template<typename A>
int call(int (*f)(A), A a) {
return f(a);
}
int main()
{
int a = call(foo)
, b = call(foo, 0)
, c = call(Foo())
, d = call(Foo(), 0);
std::cout << a << ',' << b << ',' << c << ',' << d << '\n'; // 0,1,2,3
}
The call overloads can be made more generic by adding return type deduction. In C++11, this is possible even with function objects by using decltype rsp. result_of. For brevity, I will post only the new function signatures, as the bodies don't need to be changed in this case:
template<typename F>
auto call(F f) -> decltype(f());
template<typename R>
R call(R (*f)());
template<typename F, typename A>
auto call(F f, A a) -> decltype(f(a));
template<typename R, typename A>
R call(R (*f)(A), A a);

Is there a generic way to adapt a function template to be a polymorphic function object?

I have some function templates, for example
template <typename T>
void foo(T);
template <typename T>
void bar(T);
// others
and I need to pass each one to an algorithm that will call it with various types, e.g.
template <typename F>
void some_algorithm(F f)
{
// call f with argument of type int
// call f with argument of type SomeClass
// etc.
}
I can't pass in my function template uninstantiated, but I can't instantiate it with any specific type either because some_algorithm will need to call it with arguments of several different types.
I could adapt my function templates to be polymorphic function objects, e.g.
struct foo_polymorphic
{
template <typename T>
void operator()(T t)
{
foo(t);
}
};
and then pass it as some_algorithm(foo_polymorphic()). But this requires writing a separate adapter for each of my function templates.
Is there a generic way of adapting a function template to be a polymorphic function object, i.e. some mechanism that I can re-use for each of the function templates I need to adapt, without having to declare something separately for each one?
The short version of the problem is given an overloaded name f, how to concisely write an object ff such that ff(a0, a1, a2, ...) ultimately calls f(a0, a1, a2, ...).
A polymorphic functor, how you point out yourself, is the usual solution. But it must be defined out of line (since it has a template member), so I'll consder that not concise enough for the purposes of my answer.
Currently lambda expressions yield a monomorphic functor, so they're close but not quite there.
// set of functions overloaded on int and double
void f(int);
void f(double);
auto ff = [](int i) { return f(i); };
As GMan pointed out in the comments polymorphic lambdas would (should?) be the solution to concisely write polymorphic functors inline.
In the meantime, it is possible to write a make_overload helper that combines multiple functors into one, such that
auto ff = make_overload(
[](int arg0) { return f(arg0); }
, [](double arg0) { return f(arg0); } );
would 'capture' the whole overload set. Perhaps a Boost.Preprocessor macro could help here, so that auto ff = POLYMORPHIC_LAMBDA( 1, (int)(double), { return f(arg0); } ); be used inline. I suspect there are arity restrictions however (hence the first macro argument), unlike the usual out-of-line hand-written polymorphic functor solution; so this wouldn't help with e.g. variadic function templates.
Why couldn't you use template template parameters? You said you can't pass your template uninstantiated, but I'm not sure if you've heard of this before, tell me if you have and it won't work.
I don't know what your code structure looks like, but can you do something like
I know this works, don't know if it's what yo uwant though:
template<typename T>
T some_algorithm(T data) { return T(); } // just returning nothing for example
template<typename T, T(*Something)(T)>
class FuncClass {
public:
T run(T data) { return Something(data); }
};
template<typename T, typename Functor>
void apply_algorithm(T data) {
Functor F;
F.run(data);
}
int main() {
int mydata = 4;
apply_algorithm<int, FuncClass<int, some_algorithm<int> > >(mydata);
cin.get();
}

How to call a templated function if it exists, and something else otherwise?

I want to do something like
template <typename T>
void foo(const T& t) {
IF bar(t) would compile
bar(t);
ELSE
baz(t);
}
I thought that something using enable_if would do the job here, splitting up foo into two pieces, but I can't seem to work out the details. What's the simplest way of achieving this?
There are two lookups that are done for the name bar. One is the unqualified lookup at the definition context of foo. The other is argument dependent lookup at each instantiation context (but the result of the lookup at each instantiation context is not allowed to change behavior between two different instantiation contexts).
To get the desired behavior, you could go and define a fallback function in a fallback namespace that returns some unique type
namespace fallback {
// sizeof > 1
struct flag { char c[2]; };
flag bar(...);
}
The bar function will be called if nothing else matches because the ellipsis has worst conversion cost. Now, include that candidates into your function by a using directive of fallback, so that fallback::bar is included as candidate into the call to bar.
Now, to see whether a call to bar resolves to your function, you will call it, and check whether the return type is flag. The return type of an otherwise chosen function could be void, so you have to do some comma operator tricks to get around that.
namespace fallback {
int operator,(flag, flag);
// map everything else to void
template<typename T>
void operator,(flag, T const&);
// sizeof 1
char operator,(int, flag);
}
If our function was selected then the comma operator invocation will return a reference to int. If not or if the selected function returned void, then the invocation returns void in turn. Then the next invocation with flag as second argument will return a type that has sizeof 1 if our fallback was selected, and a sizeof greater 1 (the built-in comma operator will be used because void is in the mix) if something else was selected.
We compare the sizeof and delegate to a struct.
template<bool>
struct foo_impl;
/* bar available */
template<>
struct foo_impl<true> {
template<typename T>
static void foo(T const &t) {
bar(t);
}
};
/* bar not available */
template<>
struct foo_impl<false> {
template<typename T>
static void foo(T const&) {
std::cout << "not available, calling baz...";
}
};
template <typename T>
void foo(const T& t) {
using namespace fallback;
foo_impl<sizeof (fallback::flag(), bar(t), fallback::flag()) != 1>
::foo(t);
}
This solution is ambiguous if the existing function has an ellipsis too. But that seems to be rather unlikely. Test using the fallback:
struct C { };
int main() {
// => "not available, calling baz..."
foo(C());
}
And if a candidate is found using argument dependent lookup
struct C { };
void bar(C) {
std::cout << "called!";
}
int main() {
// => "called!"
foo(C());
}
To test unqualified lookup at definition context, let's define the following function above foo_impl and foo (put the foo_impl template above foo, so they have both the same definition context)
void bar(double d) {
std::cout << "bar(double) called!";
}
// ... foo template ...
int main() {
// => "bar(double) called!"
foo(12);
}
litb has given you a very good answer. However, I wonder whether, given more context, we couldn't come up with something that's less generic, but also less, um, elaborate?
For example, what types can be T? Anything? A few types? A very restricted set which you have control over? Some classes you design in conjunction with the function foo? Given the latter, you could simple put something like
typedef boolean<true> has_bar_func;
into the types and then switch to different foo overloads based on that:
template <typename T>
void foo_impl(const T& t, boolean<true> /*has_bar_func*/);
template <typename T>
void foo_impl(const T& t, boolean<false> /*has_bar_func*/);
template <typename T>
void foo(const T& t) {
foo_impl( t, typename T::has_bar_func() );
}
Also, can the bar/baz function have just about any signature, is there a somewhat restricted set, or is there just one valid signature? If the latter, litb's (excellent) fallback idea, in conjunction with a meta-function employing sizeof might be a bit simpler. But this I haven't explored, so it's just a thought.
I think litb's solution works, but is overly complex. The reason is that he's introducing a function fallback::bar(...) which acts as a "function of last resort", and then goes to great lengths NOT to call it. Why? It seems we have a perfect behavior for it:
namespace fallback {
template<typename T>
inline void bar(T const& t, ...)
{
baz(t);
}
}
template<typename T>
void foo(T const& t)
{
using namespace fallback;
bar(t);
}
But as I indicated in a comment to litb's original post, there are many reasons why bar(t) could fail to compile, and I'm not certain this solution handles the same cases. It certainly will fail on a private bar::bar(T t)
If you're willing to limit yourself to Visual C++, you can use the __if_exists and __if_not_exists statements.
Handy in a pinch, but platform specific.
EDIT: I spoke too soon! litb's answer shows how this can actually be done (at the possible cost of your sanity... :-P)
Unfortunately I think the general case of checking "would this compile" is out of reach of function template argument deduction + SFINAE, which is the usual trick for this stuff. I think the best you can do is to create a "backup" function template:
template <typename T>
void bar(T t) { // "Backup" bar() template
baz(t);
}
And then change foo() to simply:
template <typename T>
void foo(const T& t) {
bar(t);
}
This will work for most cases. Because the bar() template's parameter type is T, it will be deemed "less specialised" when compared with any other function or function template named bar() and will therefore cede priority to that pre-existing function or function template during overload resolution. Except that:
If the pre-existing bar() is itself a function template taking a template parameter of type T, an ambiguity will arise because neither template is more specialised than the other, and the compiler will complain.
Implicit conversions also won't work, and will lead to hard-to-diagnose problems: Suppose there is a pre-existing bar(long) but foo(123) is called. In this case, the compiler will quietly choose to instantiate the "backup" bar() template with T = int instead of performing the int->long promotion, even though the latter would have compiled and worked fine!
In short: there's no easy, complete solution, and I'm pretty sure there's not even a tricky-as-hell, complete solution. :(
//default
//////////////////////////////////////////
template <class T>
void foo(const T& t){
baz(t);
}
//specializations
//////////////////////////////////////////
template <>
void foo(const specialization_1& t){
bar(t);
}
....
template <>
void foo(const specialization_n& t){
bar(t);
}
Are you not able to use full specialisation here (or overloading) on foo. By say having the function template call bar but for certain types fully specialise it to call baz?