Question

I need to use a function's/functor's returned value without knowing what type it is (that is, as a template).

While I could pass it over to a second function without a problem:

template <typename T>
void DoSomething(T value);

...

DoSomething(FunctionWhoseReturnedTypeIsUnknown(...));

I want to use the returned value inline (without the need to call a second function):

WhatGoesHere? x=FunctionWhoseReturnedTypeIsUnknown(...);

The two methods seem conceptually identical to me (generic-programming-wize), but can the latter be achived in C++?

Was it helpful?

Solution

Not yet. In C++0X you'll be able to use auto as WhatGoesHere. There is already experimental support for this in some compilers (gcc 4.4 for instance).

OTHER TIPS

Until the auto keyword makes it really trivial, one can rely on the convention that function objects provide certain typedef's, including result_type. One just needs to wrap a plain function into a function object. The standard "functional" header provides some (pointer_to_unary_function/pointer_to_binary_function in addition to a couple of member function wrappers). When these are not enough, boost library provides more powerful wrappers.

#include <iostream>
#include <boost/function.hpp>
#include <boost/bind.hpp>

int answer()
{
    return 42;
}

template <class T>
T unknown()
{
    return T();
}

template <class Function>
void foobar(Function unknown)
{
    typename Function::result_type x = unknown();
    std::cout << x << '\n';
}

int main()
{
    foobar(boost::function<int()>(answer));
    foobar(boost::bind(unknown<int>));
}

And below's an example, how you might add a pointer_to_zeronary_function. (I suppose the helper function that helps you create one, ptr_fun, might be added to the standard namespace as well as an overload(?)

template <class T>
class pointer_to_zeronary_function
{
    typedef T(*zeronary_func)();
    zeronary_func func;
public:
    typedef T result_type;
    pointer_to_zeronary_function(zeronary_func f): func(f) {}
    T operator()() const
    {
        return func();
    }
};

template <class T>
pointer_to_zeronary_function<T> ptr_fun(T(*f)())
{
    return pointer_to_zeronary_function<T>(f);
}

...
//usage:
foobar(ptr_fun(answer));

It depends on your specific use case but sometimes boost::any can be used:

#include <iostream>
#include <boost/any.hpp>

namespace {
  template <class T>
  T return_arg(T t) {
    return t;
  }
}

int main() {
  try {  
    boost::any i = return_arg(1);
    boost::any s = return_arg("a string");
    std::cout << boost::any_cast<int>(i) << " "
          << boost::any_cast<const char*>(s)
          << std::endl;
  }
  catch(const boost::bad_any_cast &) {
      return 1;
  }
}

C++0x introduces the concept of an inferred variable type by using the keyword auto.

auto x = SomeFunction();

The result is the same as C#'s var keyword: a strongly typed variable whose type is the return type of the expression.

In the absence of C++0x there is no good way to achieve this outside of a template. If there ways, C++0x would have no need for this feature.

This is really late, but I was trying to figure out how to do this and ran into this question. The environment I'm using can't use C++11 (aka C++0x) or Boost, although both of those are awesome, so I figured I'd post how I figured out to do this without either for the sake of posterity.

As UncleBens alluded to, the functional header in the STL has some useful features if you aren't using C++11 or Boost: http://www.cplusplus.com/reference/std/functional/

This problem is a bit more general than just not wanting to call a second template function. For example, one might want to build a vector of the return type of a functor, in which case calling a second template function might not work.

By using some function overloading (to operate on both function pointers and functors) and stl's , we can make this work. Here's an example that prints out the result of a one-argument functor/function argument after declaring the variable explicitly:

#include <iostream>
#include <functional>

using namespace std;


// Simple function [pointer] that adds one to its argument
int addOne(int n)
{
    return n + 1;
}

// Simple functor that multiplies its argument by two
class timesTwo
{
    public:
    int operator()(int n) const { return n * 2; }
};


// Simple higher-order function: takes a functor f and calls f on n, returning the result
// This is your template function in which you want to know the return type of f
template <typename Functor>
void printResultImpl(Functor f, typename Functor::argument_type n)
{
    typename Functor::result_type r = f(n);
    cout << r << endl;
}


// Wrapper function for function pointer
template <typename Arg, typename Result>
void printResult(Result (*f)(Arg), Arg n)
{
    printResultImpl(ptr_fun(f), n);
}

// Wrapper function for functor (function object)
template <typename Functor, typename Arg>
void printResult(Functor f, Arg n)
{
    printResultImpl(bind1st(mem_fun(&Functor::operator()), &f), n);
}


// Prints out 8 then 14
int main()
{
    printResult(addOne, 7);
    printResult(timesTwo(), 7);
}

There are a couple limitations to this method: 1. You can't have your function return the result type of the functor (since the wrapper function doesn't know the result type) 2. It relies upon unary_function or binary_function in the stl. As UncleBens demonstrated, it's possible to extend to other types - simply follow the pattern of the declarations in : http://www.cplusplus.com/reference/std/functional/

But it worked for what I needed; maybe it'll work for someone else.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top