2015-12-28 45 views
3

請看下面的代碼。在捕獲lambda表達式的情況下,它將工作並編譯得很好。使用綁定調用表達我會得到一個超載表達表達錯誤從綁定與lambda函數獲取運算符()的類型

main.cpp:13:60: error: decltype cannot resolve address of overloaded function 
using FuncType = decltype(&std::decay<T>::type::operator()); 

我如何代碼綁定功能,這使得我得到了運營商的類型()方法時,雖然?綁定類型是std::_Bind<void (*(std::_Placeholder<2>, std::_Placeholder<1>))(int, int)>,我也沒有完全理解;我知道void(*)(int,int)作爲一個指向int,int和返回void的函數的指針。我想我不明白的語法void *(x,y)(int,int);基本上是x,y部分。我假設畢竟模板的東西有一個方法void operator()(int,int)將得到解決bind_f(x,y)將調用,我試圖捕獲該類型。

#include <iostream> 
#include <functional> 
#include <type_traits> 

void tester(int x, int y) { 
    std::cout << " x = " << x << " y = " << y << std::endl; 
} 

template <typename T> 
class TypeChecker; 

template <typename T> 
using FuncType = decltype(&std::decay<T>::type::operator()); 

int main() { 
    using namespace std::placeholders; 
    auto bind_f = std::bind(tester, _2, _1); 
    bind_f(1,2);        

    int y = 5;        

    auto lambda = [y]() {     
     std::cout << " y = " << y << std::endl; 
    };           

    typedef FuncType<decltype(lambda)> x1;    
    typedef FuncType<decltype(bind_f)> x2;    

    //TypeChecker<decltype(bind_f)> t2;  

}            
+3

一個bind表達式有一個模板化的調用操作符[接受任意數量和種類的參數](https://ideone.com/K2nzuT)。一個非多態的lambda擁有一個非模板調用操作符。 –

+1

我可以問一下,你爲什麼想要首先使用綁定?或者這僅僅是爲了教化?我並不是說這個問題不好,不要誤解,只是指出實際的答案是「不要使用綁定」,因爲它的使用被推薦爲不支持lambda(特別是在14中有lambda類型) )。 –

+0

這是有道理的,是的,我創造的東西涵蓋了所有的情況,但一般情況下,我想使它不能用於綁定我只是覺得有人可能會要求它與綁定一起工作。我想知道是否有一種方法可以使FuncType這樣,它將允許使用FuncType = decltype(T :: operator()(std :: declval )這樣的'template ()...))(TS ...); ' – bjackfly

回答

0

就像評論者說,你bind對象的operator()是,你不能簡單地bind在沒有選擇的版本你想有一個模板(即超載)功能。

當我們使我們的typedef,我們可以通過添加另一個模板參數FuncTypestatic_cast「荷蘭國際集團,以選擇相應的功能,然後是明確解決這一問題:

template <typename T, typename... U> 
using FuncType = decltype(static_cast<void(T::*)(U...) const>(&std::decay<T>::type::operator())); 

然後

auto bind_f = std::bind(tester, _2, _1);       

int y = 5;        

auto lambda = [y]() {     
    std::cout << " y = " << y << std::endl; 
};           

using x1 = FuncType<decltype(lambda)>; 
using x2 = FuncType<decltype(bind_f), int&&, int&&>; 

x1 p = &decltype(lambda)::operator(); 
(lambda.*p)(); 

x2 q = &decltype(bind_f)::operator(); 
(bind_f.*q)(1,2); 

Live Demo

輸出:

Y = 5

x = 2時y = 1

Nir Friedman when he said同意只是避免bind完全; lambda使事情變得更容易。

+0

我不認爲'std :: decay :: type'部分在模板類型別名中是必需的,但我將它留在那裏。 – AndyG

+0

還沒有嘗試過,但假設如果我想要返回類型是變量,我只是將其作爲另一個模板參數在這種情況下添加。意思是如果我的operator()沒有返回void – bjackfly

+0

@bjackfly:是的,稍作修改:[Demo](http://coliru.stacked-crooked.com/a/05bfeb038eb60fe7)。這不是最乾淨的例子,但你明白了。 – AndyG

相關問題