2012-09-21 40 views
2

所以我有以下代碼:C++ 11 LAMBDA模板Infering

#include <iostream> 

template <typename T> 
class funcky 
{ 
    public: 
    funcky(char const* funcName, T func) 
     : name(funcName), myFunc(func) 
    { 
    } 

    //private: 
    char const* name; 
    T myFunc; 
}; 

#if 0 
int main(void) 
{ 
    char const* out = "nothing"; 

    // requires template args 
    funcky test("hello", [&](int x, int y) -> int 
    { 
    out = "YES"; 
    return x + y; 
    }); 

    std::cout << test.name << " = " << test.myFunc(1, 2) << std::endl; 
    std::cout << test.name << " = " << out << std::endl; 

    return 0; 
} 

int main2(void) 
{ 
    funcky<void(*)(void)> test("hello", [&, this](void) -> void 
    { 
    std::cout << this->name << std::endl; 
    }); 

    test.myFunc(); 

    return 0; 
} 
#endif 

int main(void) 
{ 
    char const* out = "nothing"; 

    auto myFunc = [&](int x, int y) -> int 
    { 
    out = "YES"; 
    return x + y; 
    }; 
    funcky<decltype(myFunc)> test("hello", myFunc); 

    std::cout << test.name << " = " << test.myFunc(1, 2) << std::endl; 
    std::cout << test.name << " = " << out << std::endl; 

    return 0; 
} 

頂塊是一個函數持有人持有的λ和它的名稱。

接下來是我想使用API​​方式,但由於沒有指定模板參數而失敗。

之後,我想知道是否可以在未聲明的lambda中使用特定類型的「this」(例如funcky)。妄想。

最終的代碼是編譯但在funcky構造函數和decltype之外使用lambda的代碼。

在C++ 11中可以這樣做嗎?我如何完成所說的事情?

另外,除非它可以具有相同的API,儘量不要猜測我在做什麼,就好像我不能這樣做,我只會以更簡單的方式重寫它。這是不值得的努力。

回答

3

如果您想爲用戶提供一種方法來爲您的課程提供回調,最好使用std::function,因爲在函數/函子類型上對模板進行模板化並不是一件非常有用的事情,因爲你經歷過。

問題出在您不能隨便拿什麼東西的事實。您應該對可以作爲回調傳遞的東西有明確的要求,因爲您應該知道以後如何調用它。關於爲什麼我使構造函數成爲模板,請參閱this

#include <functional> 
#include <utility> 

struct X{ 
    template<class F> 
    X(F&& f) : _callback(std::forward<F>(f)) {} // take anything and stuff it in the 'std::function' 

private: 
    std::function<int(int,int)> _callback; 
}; 

int main(){ 
    X x([](int a, int b){ return a + b; }); 
} 

但是,如果你不知道回調將如何被調用(比如,當用戶經過論證以後),但要支持,在模板的類型回調的簽名

#include <iostream> 
#include <functional> 
#include <utility> 

template<class Signature> 
struct X{ 
    template<class F> 
    X(F&& f) : _callback(std::forward<F>(f)) {} // take anything and stuff it in the 'std::function' 

private: 
    std::function<Signature> _callback; 
}; 

int main(){ 
    X<int(int,int)> x1([](int a, int b){ return a + b; }); 
    X<void()> x2([]{ std::cout << "wuzzah\n";}); 
} 
+0

啊,所以沒有辦法獲得兩全其美,並且讓Signature隱含或者從lambda算起? – Jookia

+3

@Jookia不,這不會發生。你應該考慮可卡因而不是拉姆達斯。蘭姆達什在任何方面都不是特別的。 'struct try_to_deduce_a_signature_for_this_one {template void f(T); };' –

+0

啊。即使decltype? – Jookia

3

喜歡的東西

template<typename Functor> 
funcky<typename std::decay<Functor>::type> 
make_funcky(const char* name, Functor&& functor) 
{ return { name, std::forward<Functor>(functor) }; } 

可以爲東西里有幫助科:

auto test = make_funcky("hello", [&](int x, int y) -> int 
{ 
    out = "YES"; 
    return x + y; 
}); 

然而,lambda表達式this內始終指的是即時this外表達的。這不是延遲對調用時存在的某些this的引用 - 它不是一個隱式參數。因此,要爲其「另一種類型」設置是沒有意義的。