我需要使用函数/函数的返回值,而不知道它是什么类型(即作为模板)。
虽然我可以将它传递给第二个函数而没有问题:
template <typename T>
void DoSomething(T value);
...
DoSomething(FunctionWhoseReturnedTypeIsUnknown(...));
我想使用返回的内联值(无需调用第二个函数):
WhatGoesHere? x=FunctionWhoseReturnedTypeIsUnknown(...);
这两种方法在概念上看起来与我相同(generic-programming-wize),但后者可以在C ++中实现吗?
答案 0 :(得分:5)
直到auto关键字使它变得非常简单,人们可以依赖函数对象提供某些typedef的约定,包括result_type。只需将普通函数包装到函数对象中即可。标准的“functional”头文件提供了一些(除了几个成员函数包装器之外还有pointer_to_unary_function / pointer_to_binary_function)。当这些还不够时,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>));
}
以下是一个示例,您可以如何添加pointer_to_zeronary_function。 (我想帮助你创建一个ptr_fun的辅助函数可能会添加到标准命名空间以及重载(?)
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));
答案 1 :(得分:4)
还没有。在C ++ 0X中,您可以将auto
用作WhatGoesHere
。在某些编译器中已经有了实验性支持(例如gcc 4.4)。
答案 2 :(得分:2)
这取决于您的具体用例,但有时可以使用boost::any:
#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;
}
}
答案 3 :(得分:1)
C ++ 0x通过使用关键字auto引入了推断变量类型的概念。
auto x = SomeFunction();
结果与C#的var关键字相同:一个强类型变量,其类型是表达式的返回类型。
在没有C ++ 0x的情况下,没有好的方法可以在模板之外实现这一点。如果有方法,C ++ 0x将不需要此功能。
答案 4 :(得分:1)
这已经很晚了,但我试图弄清楚如何做到这一点并遇到了这个问题。我正在使用的环境不能使用C ++ 11(又名C ++ 0x)或Boost,虽然这些都很棒,所以我想我会发布如何在没有为此的情况下做到这一点后人。
正如UncleBens所提到的,如果你不使用C ++ 11或Boost,STL中的函数头有一些有用的功能: http://www.cplusplus.com/reference/std/functional/
这个问题比不想调用第二个模板函数更普遍。例如,有人可能想要构建一个仿函数的返回类型的向量,在这种情况下,调用第二个模板函数可能不起作用。
通过使用一些函数重载(对函数指针和仿函数进行操作)和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);
}
此方法有一些限制: 1.您不能让函数返回仿函数的结果类型(因为包装函数不知道结果类型) 它依赖于stl中的unary_function或binary_function。正如UncleBens所展示的那样,它可以扩展到其他类型 - 只需遵循以下声明的模式: http://www.cplusplus.com/reference/std/functional/
但它适用于我需要的东西;也许这对其他人有效。