2017-10-11 47 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