簡體   English   中英

在C ++中推斷函數或函子的返回類型

[英]Inferring the return type of a function or functor in C++

我需要使用函數/函數的返回值,而不知道它是什么類型(即作為模板)。

雖然我可以將它傳遞給第二個函數而沒有問題:

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

...

DoSomething(FunctionWhoseReturnedTypeIsUnknown(...));

我想使用返回的內聯值(無需調用第二個函數):

WhatGoesHere? x=FunctionWhoseReturnedTypeIsUnknown(...);

這兩種方法在概念上看起來與我相同(generic-programming-wize),但后者是否可以在C ++中實現?

在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));

還沒。 在C ++ 0X中,您將能夠將auto用作WhatGoesHere 在一些編譯器中已經有了實驗性支持(例如gcc 4.4)。

這取決於您的具體用例,但有時可以使用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;
  }
}

C ++ 0x通過使用關鍵字auto引入了推斷變量類型的概念。

auto x = SomeFunction();

結果與C#的var關鍵字相同:一個強類型變量,其類型是表達式的返回類型。

在沒有C ++ 0x的情況下,沒有好的方法可以在模板外實現這一點。 如果有方法,C ++ 0x將不需要此功能。

這真的很晚了,但我試圖弄清楚如何做到這一點並遇到了這個問題。 我正在使用的環境不能使用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。你不能讓函數返回仿函數的結果類型(因為包裝器函數不知道結果類型)2。它依賴於stl中的unary_function或binary_function。 正如UncleBens所展示的那樣,它可以擴展到其他類型 - 只需遵循以下聲明的模式: http ://www.cplusplus.com/reference/std/functional/

但它適用於我需要的東西; 也許它會為別人工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM