2016-07-29 97 views
1

我想編寫代碼來做到這一點(用於演示目的編寫的代碼)類似的事情:結束語一個模板函數調用的拉姆達

template <typename F, typename Args...> 
inline auto runFunc(F func) -> foo 
{ 
    return foo([func](Args... args) -> std::result_of<F>::type 
     { 
      // Do something before calling func 
      func(args...); 
      // Do something after call func 
     }); 
} 

所以基本上我想寫一個返回的功能該對象採用與模板化函數類型匹配的lambda。很明顯,這段代碼不起作用,因爲我沒有定義的參數。我將如何在C++ 11中解決這個問題?

+4

你能提供更多關於你想要做什麼的背景嗎? – templatetypedef

+0

'runFunc(F func)'後的' - > foo'沒有任何意義。試試'decltype(foo([func](Args ... args)'...'))' – Czipperz

+0

什麼是'foo()'?你只是想裝飾'func'? – Barry

回答

0

仍然不確定它這是你要搜索的內容,我的風險發佈:

#include <iostream> 

struct foo 
{ 
    template<typename T> 
    foo(T lambda) 
    { 
     lambda(1, 2); 
    } 
}; 

template <typename F, typename... Args> 
inline typename std::result_of<F>::type runFunc(F func) 
{ 
    return foo(
     [func](Args... args) 
     { 
      std::cout << "Before"; 
      func(args...); 
      std::cout << "After"; 
     } 
    ); 
} 

struct print 
{ 
    void operator()(int i) const 
    { 
     std::cout << i << std::endl; 
    } 

    void operator()(int i, int j) const 
    { 
     std::cout << i << " " << j << std::endl; 
    } 
}; 

int main() 
{ 
    runFunc<print, int, int>(print()); 
} 
+0

請注意您的解決方案需要C++ 14。你不能從C++ 11中的函數返回一個lambda表達式,你需要用一個命名類型(例如:'std :: function',函數指針...)來包裝它。 – KABoissonneault

+0

哦,我剛剛意識到lambda不是函數返回的對象。那麼,我的第一點仍然是 – KABoissonneault

+0

@KABoissonneault:哪一部分比OP的代碼要求*更多*? – lorro

1
template<class F_before, class F, class F_after> 
struct decorate_func_t { 
    F_before f0; 
    F f1; 
    F_after f2; 

    template<class...Args> 
    typename std::result_of<F(Args...)>::type operator()(Args&&...args)const{ 
    f0(); 
    auto r = f1(std::forward<Args>(args)...); 
    f2(); 
    return r; 
    } 
}; 
template<class F_before, class F, class F_after> 
decorate_func_t<F_before, F, F_after> 
decorate_func(F_before before, F f, F_after after){ 
    return {std::move(before), std::move(f), std::move(after)}; 
} 

然後:

template <typename F, typename Args...> 
inline auto runFunc(F func) -> foo 
{ 
    return foo(decorate_func(
     []{/* Do something before calling func */}, 
     func, 
     []{/* Do something after call func */ } 
    }; 
} 

在C++ 11缺乏auto參數lambdas使得你可以做的最好。

在C++ 14這個很簡單:

template <class F> 
auto runFunc(F func) 
{ 
    return foo(
    [func](auto&&... args) // ->decltype(auto) maybe 
    { 
     // Do something before calling func 
     auto r = func(decltype(args)(args)...); 
     // Do something after call func 
     return r; 
    } 
); 
} 

注意,很多名義上是C++ 11編譯器實際上支持lambda表達式auto參數。

0

您可以使用一個支撐結構如下面的例子:

#include<type_traits> 
#include<cassert> 

struct foo { 
    template<typename F> 
    foo(F f) { assert(42 == f(42)); } 
}; 

template<typename> 
struct S; 

template<typename R, typename... Args> 
struct S<R(*)(Args...)> { 
    template <typename F> 
    static auto runFunc(F func) -> foo 
    { 
     return foo{[func](Args... args) -> R 
      { 
       // Do something before calling func 
       auto r = func(args...); 
       // Do something after call func 
       return r; 
      }}; 
    } 
}; 

template<typename F> 
inline auto runFunc(F func) -> foo 
{ 
    return S<F>::runFunc(func); 
} 

int f(int i) { return i; } 

int main() { 
    runFunc(f); 
} 

對於這我不清楚是什麼問題的情況下,我不知道我有你問什麼了。
我希望上面的代碼可以幫助你。