C++ 推断C+中函数或函子的返回类型+;

C++ 推断C+中函数或函子的返回类型+;,c++,generic-programming,C++,Generic Programming,我需要使用函数/functor的返回值,而不知道它是什么类型(即作为模板) 虽然我可以毫无问题地将其传递给第二个函数: template <typename T> void DoSomething(T value); ... DoSomething(FunctionWhoseReturnedTypeIsUnknown(...)); 这两种方法在概念上似乎与ME(泛型编程WIZE)相同,但后者可以在C++中实现吗?< P>C++ +0x使用关键字Auto.I/O引入了推断变量类型

我需要使用函数/functor的返回值,而不知道它是什么类型(即作为模板)

虽然我可以毫无问题地将其传递给第二个函数:

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

...

DoSomething(FunctionWhoseReturnedTypeIsUnknown(...));

这两种方法在概念上似乎与ME(泛型编程WIZE)相同,但后者可以在C++中实现吗?

< P>C++ +0x使用关键字Auto.I/O引入了推断变量类型的概念。p>
auto x = SomeFunction();
结果与C#的var关键字相同:一个强类型变量,其类型是表达式的返回类型


在缺少C++0x的情况下,没有好的方法在模板之外实现这一点。如果有办法,C++0x将不需要此功能

还没有。在C++0X中,您可以使用
auto
作为
whatgoesher
。在某些编译器(例如gcc 4.4)中已经有了对此的实验支持。

这取决于您的特定用例,但有时可以使用:

#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;
  }
}
#包括
#包括
名称空间{
模板
T返回参数(T T){
返回t;
}
}
int main(){
试试{
boost::any i=返回参数(1);
boost::any s=return_arg(“字符串”);

std::cout在auto关键字使其变得非常简单之前,我们可以依赖函数对象提供特定typedef的约定,包括result_type。我们只需要将普通函数包装到函数对象中。标准的“functional”头提供一些(除了两个成员函数包装器之外,指针指向一元函数/指针指向二元函数)。当这些还不够时,boost库提供了更强大的包装器

#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>));
}
#包括
#包括
#包括
int答案()
{
返回42;
}
模板
T未知()
{
返回T();
}
模板
void foobar(函数未知)
{
typename函数::result_type x=unknown();

std::cout这真的很晚了,但我正试图弄清楚如何做到这一点,遇到了这个问题。我使用的环境不能使用C++11(又名C++0x)或Boost,尽管这两种都非常棒,所以为了子孙后代,我想发布我是如何做到这一点的

正如UncleBens提到的,如果您不使用C++11或Boost,STL中的函数头具有一些有用的特性:

这个问题比不想调用第二个模板函数更普遍。例如,可能需要构建函子返回类型的向量,在这种情况下,调用第二个模板函数可能不起作用

通过使用一些函数重载(对函数指针和函子进行操作)和stl,我们可以实现这一点。下面的示例在显式声明变量后打印出单参数函子/函数参数的结果:

#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);
}
#包括
#包括
使用名称空间std;
//向其参数中添加一个的简单函数[指针]
int addOne(int n)
{
返回n+1;
}
//将参数乘以2的简单函子
课时二
{
公众:
int运算符()(int n)常量{返回n*2;}
};
//简单的高阶函数:取一个函子f并对n调用f,返回结果
//这是您想要知道f的返回类型的模板函数
模板
void printResultImpl(Functor f,typename Functor::argument\u type n)
{
类型名函子::结果类型r=f(n);

不幸的是,在这方面你有点塞满了C++0x之前的版本。可能值得一看boost::any,但我不知道这在这种情况下是否有效-从未尝试过。@Stefano:使用程序员的万能疗法:另一个间接层次。在这种情况下,正如问题中已经提到的,这将是一个函数模板VS2008似乎能识别“auto”关键字(它把它涂成蓝色)但是,使用它时,会出现一个“缺失类型说明符”编译器错误。在VC++中,“代码>自动代码/代码>的任何概念都在现有C++中被用作存储类说明符,类似于代码>静态< /代码>和<代码>登记器> />代码,它是本地变量的默认值。您可以省略它,并具有相同的含义。@它是被重新使用的。C++可以追溯到B的时代。我不记得它最初是用来做什么的。它是C和今天C++的一部分,但在今天的意义上不是很有用;-对于历史记录来说:登记不存在B(根据),在C中出现在1975()中。重新命名你的问题。我们可以看到,这是一个关于C++和泛型编程的问题,因为你创建了一个问题,它被标记为C++和泛型编程。我们在标题中需要的是问题的提示。让其他有类似问题的人更容易找到你的。所以应该是可搜索的。问问题时,我一般都知道这些惯例——至少在基本层面上是这样。但似乎人们必须通过反复使用STL、其他编写良好的模板库以及阅读Josuttis和Vandevoorde的模板书来学习这些东西。有没有这些惯用的typedef的简单列表?这样我将知道我应该确保什么是在我写的任何模板中,更不用说知道如何使用它们了。
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));
#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);
}