2016-02-11 82 views
1

我用auto來存儲就在自動分配構建一個lambda,但今天我看着this interesting paper on functional programming using c++ templates和跨越這些代碼來:使用自動爲定義的函數

template < typename T , typename Ops > 
T fold (Linked <T > * p) 
{ 
    T acc = Ops :: initial() ; 
    while (p) { 
    acc = Ops :: bin (acc , p - > head) ; 
    p = p - > tail ; 
    } 
    return acc ; 
} 

// later, in main(): 

auto sumup = fold <int , IntOps >; 

我想了解sumup的類型是什麼,因爲它不是分配給fold的輸出,而是分配給實際功能fold本身!我決定看看auto顯示使用的各種方式here。我假設這個auto的使用屬於該頁面上的(1),這是一個通用變量初始化器。什麼是不明確的是sumup的類型是什麼?

而且,將auto可能是同一這裏這樣做:

using functionType = int (Linked<int>*); 
    functionType sumup = fold <int , IntOps >; 

這可能是不正確的,但我很好奇,如果我的想法是正確的方向。當實例化時,fold <int , IntOps >將返回int並採用Linked<int>*的單個參數,因此我的using聲明是說同樣的事情?這是using聲明一個真正的「類型」,是auto抵達這個using相同的扣除?

+4

非常接近。簡單''自動'衰減,所以你得到一個函數指針類型 - 'int(*)(Linked *)' –

+0

既然你有答案,我想說我發現這個代碼的問題有問題。有人會很難弄清楚這個「sumup」是什麼。 – SergeyA

+0

@SergeyA是真的,事實上,這是一個普遍的弱點,在任何語言中都有隱式類型推理。動態語言會變得更糟。我仍然發現我更喜歡明確的類型聲明,除非這是很難知道的情況,最好留給編譯器。 – johnbakers

回答

1

雖然每個函數都有一個類型,但不能有該類型的表達式,也不能有變量。因此int foo(float)的類型爲int(float),但您不能擁有該類型的變量。

可以有表情和類型指針功能,所以​​的變量。例如,&foo就是這樣一個指向函數的指針。

這兩種類型顯然是密切相關的。實際上,轉換是隱含的:int (*pFoo)(float) = foo;會自動進行轉換。

你在這裏做的幾乎是一樣的:int (*sumup)(Linked<int>*) = fold <int , IntOps >;。您看到auto使定義更具可讀性。

+0

你絕對可以有函數類型的表達式。 –

+0

@ T.C .:舉例? _function調用表達式_沒有函數類型。 – MSalters

+0

'int foo(float);',id-表達式'foo'是函數類型'int(float)'的左值。 –

1

auto按照與template argument deduction相同的規則工作。也就是說,當不合格時,它會以價值取勝。既然你在這裏返回一個函數引用,它將不得不衰減到一個指針,因爲函數沒有「值類型」,具有特定的大小和內容。

您還可以使用auto&&進行捕獲,這將使sumup的類型爲int (&)(Linked<int>*),即對函數的引用。