2012-10-17 26 views
3

一些元編程代碼開始:爲什麼類型推演失敗的(非指針到)函數類型

template<class... Ts> 
class list {}; //a generic container for a list of types 

template<class in_list_type> 
class front //get the type of the first template parameter 
{ 
    template<template<class...> class in_list_less_template_type, class front_type, class... rest_types> 
    static front_type deduce_type(in_list_less_template_type<front_type, rest_types...>*); 
public: 
    typedef decltype(deduce_type((in_list_type*)nullptr)) type; 
}; 

此代碼工作正常此:

typedef typename front<list<int, float, char>>::type type; //type is int 

但是編譯失敗時第一項是函數類型:

// no matching function for call to 'deduce_type' 
typedef typename front<list<void(), float, char>>::type type; 

我現在只能訪問XCode並且無法確認這是否是si mply一個XCode錯誤。我正在使用XCode 4.5.1,使用Apple LLVM編譯器4.1。

+1

函數類型是否爲void(*)()? – imreal

+1

@Nick這是指向函數類型的指針。 void()在C++中是一個奇怪的混蛋繼父類型,當你使用std :: function 時,你可能會看到它。它基本上是你在取消引用函數指針時得到的類型。 – Brent

+0

@Brent C++不應該被使用。 :P(謝謝澄清,我不知道這件事。) – 2012-10-17 21:31:53

回答

4

當推導到deduce_type的模板參數時,front_type具有void()作爲候選。但是,這會使deduce_type的類型爲void()()(函數返回一個函數 - 如果您假定template<typename T> using alias = T;在範圍內,則返回alias<void()>())。這是一個錯誤,類型扣除失敗。

一個解決方案是讓deduce_type返回類似identity<front_type>typetypename decltype(deduce_type((in_list_type*)nullptr))::type的別名。

+0

打敗我吧。我只會添加SFINAE是爲什麼你會得到一個「不匹配函數」錯誤,而不是「你不能使用該返回類型」錯誤。 – aschepler

+0

爲什麼'void()()'錯誤? –

+1

@Kevin:因爲一個函數不能作爲一個值返回,只能是一個指向函數的指針。函數簽名只能用作類型,而不能用作對象。 – ildjarn