关于std::函数类定义的问题

Questions about the definition of std::function class

本文关键字:问题 定义 函数 std 关于      更新时间:2023-10-16

我看到它的源代码(Mac XCode,/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/functional)是

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::函数的源代码确实可以编译。为什么?

  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:感谢@Chris Drew,他指出问题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?

上述CCD_ 10实际上是CCD_ 11的捷径。我对误导感到抱歉。

我认为如果A(B)实际上是一个函数类型,那么它应该是

template<F>
class foo {...}

根据我的C++98知识,其中FA(B)

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

似乎不对。

作为一个只熟悉C++98的老人,我不理解类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*/是相对于用于匹配它的主要类模板声明的模板参数列表。

换句话说,每当用一些参数T1,...实例化类模板A时,编译器都会考虑A的主定义及其所有可见的部分专门化A<something>,试图匹配"T1,…"根据函数模板推导规则,将"某物"转换为"某物"。如果没有找到macthes,则使用主def;否则,将使用最佳匹配候选者(如果唯一)。

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

拥有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的返回值和参数。那么它有什么好处呢?

更新:

如果你想实现一个以模板为参数的模板,它本身也有一个函数参数,你可以这样做。我列出了普通模板、模板模板和所有这些函数类型的变体。希望能有所帮助://定义标准模板类样板类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