2017-10-11 44 views
-1

我看到了它的源代碼(MAC的XCode,/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/functional)是有關的std :: function類的定義問題

template<class R, class... ArgTypes>                            
class function<R(ArgTypes...)> 
    : public unary_function<T1, R>  // iff sizeof...(ArgTypes) == 1 and 
             // ArgTypes contains T1 
    : public binary_function<T1, T2, R> // iff sizeof...(ArgTypes) == 2 and 
             // ArgTypes contains T1 and T2 
{...}; 

在這裏,我有這兩個問題:

  1. 是否合法有

    class C : public A : public D {}

?它似乎是非法的,但std :: function的源代碼不會編譯。爲什麼?

  1. 是什麼

    template<class A, B> class foo<A(B)> //Can we have "<A(B)>" here? What's its meaning? {...}

意思?作爲一個只熟悉C++ 98的老人,我不明白class foo<A(B)>,我認爲類型參數列表<...>只能出現在template之後才能用於模板定義。順便說一句,我知道A(B)可以是一個函數類型。


更新1: 感謝@克里斯德魯誰指出問題1的代碼片段是來自(大)註釋中的所以它是一種僞代碼。請忘記它。所以問題一沒有了。但問題二仍然存在。


更新2: 我的意思是

class foo<A(B)> //Can we have "<A(B)>" here? What's its meaning?

class foo<A(B)> //Can we have "<...>" here? What's its meaning?

以上<...>是真的<A(B)>一條捷徑。我很抱歉有誤導性。

我想,如果A(B)是有效的函數式,那麼它應該是

template<F> 
class foo {...} 

其中FA(B),根據我的C++ 98的知識,並

template<class A, B> 
class foo<A(B)> 
{...} 

似乎不正確。

+4

你指的是libC++代碼嗎?我相信[您找到的代碼](https://github.com/llvm-mirror/libcxx/blob/master/include/functional)位於註釋塊內,並且實際上是僞代碼。 –

+3

那時候我們不得不去調試評論... – bolov

+0

@ChrisDrew OMG!它是!謝謝。但是,我仍然有第二個問題。 – Robert

回答

2

作爲一個只熟悉C++ 98的老人,我不明白class foo,並且我認爲類型參數列表< ...>只能出現在模板定義的模板之後。順便說一句,我知道A(B)可以是一個函數類型。

這是一個類模板偏特的語法:

template<class T> struct A {}; // primary class template declaration 
template<class Whatever1,class Whatever2> struct A< /*whatever*/ > {}; // class template partial specialization 

其中/*whatever*/是相對於用於匹配它的主要類模板聲明的模板的參數列表。

換句話說,只要你的類模板A進行實例化一些參數T1,...,編譯器會同時考慮A的首要定義及其所有的可見部分特例A<something>,試圖匹配‘T1,......’到'的東西'根據功能模板扣除規則。如果沒有找到macthes,則使用主要的def;否則,使用最佳匹配候選者(如果唯一的話)。

1

1)它是一個語法錯誤,:應該只在基類列表中第一個項目之前出現,那麼,應使用:

template<class R, class... ArgTypes> 
class function<R(ArgTypes...)> 
: public unary_function<T1, R> // iff sizeof...(ArgTypes) == 1 and 
            // ArgTypes contains T1 
, public binary_function<T1, T2, R> 

其實它更像是代碼片段你已經張貼在不完整的。

2)它是一個模板參數收拾一個function模板類專業化

template<typename TSome, typename TOther> class 
t_Foo{ ... }; 

// specialization for cases when TSome is the same as TOther 
template<typename T> class 
t_Foo<T, T>{ ... }; // now we have <...> after template keyword and after template name as well 
+0

對於1)源代碼編譯。我已經更新了我的問題並指出了源代碼的確切路徑。對於2),我知道參數包的含義是什麼,但我的問題是'class foo '。 – Robert

+1

@Robert看到我對你的問題的評論。你發佈的「代碼」來自'/ *功能簡介... * /'部分,只是一個評論。 –

+0

@Robert:以及評論中的評論如何在實際代碼中實現是我的答案的一部分... – Klaus

1

是合法的有class C : public A : public D {}

從來沒有看到過和gcc沒有編譯。如使用 發佈的代碼註釋,如果使用編譯條件(SFINAE)或簡單地使用超載。在GCC的實現是這樣的:

template<typename _Res, typename... _ArgTypes> 
    class function<_Res(_ArgTypes...)> 
    : public _Maybe_unary_or_binary_function<_Res, _ArgTypes...> 
     ... code continues here ... 

其中_Maybe_unary_or_binary_function超載這樣的:

/** 
    * Derives from @c unary_function or @c binary_function, or perhaps 
    * nothing, depending on the number of arguments provided. The 
    * primary template is the basis case, which derives nothing. 
    */ 
    template<typename _Res, typename... _ArgTypes> 
    struct _Maybe_unary_or_binary_function { }; 

    /// Derives from @c unary_function, as appropriate. 
    template<typename _Res, typename _T1> 
    struct _Maybe_unary_or_binary_function<_Res, _T1> 
    : std::unary_function<_T1, _Res> { }; 

    /// Derives from @c binary_function, as appropriate. 
    template<typename _Res, typename _T1, typename _T2> 
    struct _Maybe_unary_or_binary_function<_Res, _T1, _T2> 
    : std::binary_function<_T1, _T2, _Res> { }; 

template<class A, B> 
class foo<A(B)> //Can we have "<...>" here? What's its meaning? 
{...} 

它是常用的,如果你想什麼呢用函數語法編寫模板實例化,如:

foo< void(int) > f; 

是的,你可以在任何地方使用...

template <typename RETVAL, typename ... PARMS> 
class Func<RETVAL(PARMS...)> 
{ 
}; 

int main() 
{ 
    Func<void(int, float)> f; 
    Func<int()> f1; 
    Func<float(std::string)> f2; 
} 

更新:

我認爲,如果A(B)是一個有效的函數類型,那麼它應該是

template<F> 
class foo {...} 

它不是function type本身,它只是一種使用函數語法來定義模板參數的方法/語法。如果您將F作爲函數類型使用,您可以將其設置爲模板模板。但是這對任何事情都沒有幫助,因爲在使用該類型的類中,必須訪問定義的每個參數。如果您在此處只有F,則只能將此F轉發給其他模板,因爲您無法在模板類本身內訪問返回值和參數F。那有什麼好處呢?

UPDATE:

如果你想實現一個模板,這需要一個模板參數,它本身需要一個函數的參數,你可以做到這一點。我列出了來自普通模板,模板模板的所有變體以及所有這些也與函數類型。希望有幫助: //定義一個標準模板類 template class Templ {};

// define one with template template parameter 
template < template <typename> class TEMPL > 
class TemplTempl {}; 

// and now to catch a function type 
template <typename RETVAL, typename ... PARMS> class Func; 

template <typename RETVAL, typename ... PARMS> 
class Func<RETVAL(PARMS...)> 
{ 
    public: 
     static void Do() { std::cout << __PRETTY_FUNCTION__ << std::endl; } 
}; 

// and how to define a template which takes a template which takes a function type parameter? 
template < template < typename RETVAL, typename ... PARMS > class F> 
class FuncTempl{}; 

template < template < typename , typename ... > class F, typename RETVAL, typename ... PARMS > 
class FuncTemplUser 
{ 
    static void Do() { std::cout << __PRETTY_FUNCTION__ << std::endl; } 
}; 

template < template < typename , typename ... > class F, typename RETVAL, typename ... PARMS > 
class FuncTemplUser< F, RETVAL(PARMS...)> : public F<RETVAL(PARMS...)> 
{ 
    public: 
    static void Do() { std::cout << __PRETTY_FUNCTION__ << std::endl; F<RETVAL(PARMS...)>::Do(); } 
}; 



int main() 
{ 
    // using the standard templates 
    Templ<int> n1; 
    // and the template which takes a template as parm 
    TemplTempl<Templ> n2; 

    // now use one with function type 
    Func<void(int, float)> f; 
    Func<void(int, float)>::Do(); 

    FuncTempl<Func> f2; 

    FuncTemplUser<Func, void(int)> f3; 
    f3.Do(); 
} 

正如你可以看到FuncTempl正在本身以後可以使用函數類型的模板。這正是你認爲你的F將是。

+0

謝謝,但我已經更新了我的問題,以便清楚。 – Robert

+0

@Robert:更新了我的答案..如果你想要感謝我,請使用upvote按鈕;) – Klaus

+0

我知道目的,但是我對語法有疑問。如果我們只需要聲明的類型參數,那麼'template foo {...}'就足夠了。如果我們需要像A(B)這樣的函數指針類型,我們可以通過在模板類體內使用F = A(B)來實現。那麼'template foo {...}'是什麼意思? – Robert