簡體   English   中英

奇怪的模板語法<functional>

[英]Strange template syntax in <functional>

我一直在查看gcc-4.7.2中std::functionstd::bind的源代碼,並且遇到了一些我不理解的成員函數指針的語法。

我不明白的是_Maybe_wrap_member_pointer

template<typename _Tp, typename _Class>
struct _Maybe_wrap_member_pointer<_Tp _Class::*> // note no comma here
  • 為什么_Tp_Class::*之間沒有逗號?

  • 給定成員函數void foo::bar() (在我下面的示例應用程序中),_ _Tp_Class::*將在_Class::*解析?

下面是我的示例應用程序,它綁定成員函數指針和對象。 (我已經為成員函數提取了與std::bind specializations / internals相關的源代碼)

#include <iostream>
#include <functional>

template<typename T>
struct _Maybe_wrap_member_pointer;

template<typename _Tp, typename _Class>
struct _Maybe_wrap_member_pointer<_Tp _Class::*> // <-- I don't understand this
{                                                // why not <_Tp, _Class::*>  
    typedef std::_Mem_fn<_Tp _Class::*> type;    

    static type __do_wrap(_Tp _Class::* __pm)  
    {
        return type(__pm);
    }
};

template<typename _Func, typename... _BoundArgs>
struct _Bind_helper
{
    typedef _Maybe_wrap_member_pointer<typename std::decay<_Func>::type> __maybe_type;

    typedef typename __maybe_type::type __func_type;
    typedef std::_Bind<__func_type(typename std::decay<_BoundArgs>::type...)> type;
};

template<typename _Func, typename... _BoundArgs>
inline 
typename _Bind_helper<_Func, _BoundArgs...>::type
bind(_Func&& __f, _BoundArgs&&... __args)
{
    typedef _Bind_helper<_Func, _BoundArgs...>   __helper_type;
    typedef typename __helper_type::__maybe_type __maybe_type;
    typedef typename __helper_type::type         __result_type;

    return __result_type(__maybe_type::__do_wrap(std::forward<_Func>(__f)),
                                                 std::forward<_BoundArgs>(__args)...);
}

struct foo
{
    void bar()
    {
        std::cout << __func__ << std::endl;
    }
};

int main()
{
    foo f;

    std::function<void()> fun = bind(&foo::bar, f);
    fun();

    exit(0);
}

這確實是用於將成員指針類型指定為模板參數的語法。

假設你有一個班級

struct Bar
{
  int n;
};

那么指向成員Bar::n的指針必須將其類型聲明為int Bar::*

int Bar::* p = &Bar::n;

請注意, int指的是指針指向的類型, Bar::*表示“指向Bar成員的指針”。

現在你的例子的功能,

template<typename _Tp, typename _Class>
struct _Maybe_wrap_member_pointer<_Tp _Class::*> // note no comma here

接受模板參數(只有一個!),它代表了一類的構件指針類型_Class ,指向類型的非靜態數據成員_Tp

這是只有一個模板參數類模板的模板特

template <typename T>
struct _Maybe_wrap_member_pointer
{ };

我們可以使用上面的簡單類來實例化特化,如下所示:

_Maybe_wrap_member_pointer<int Bar::*>

或使用decltype

_Maybe_wrap_member_pointer<decltype(&Bar::n)>

在這兩種情況下, _Tp推導為int_Class推導為Bar

  • 為什么_Tp和_Class :: *之間沒有逗號?

jogojapan回答了這一部分

  • 給定成員函數void foo :: bar()(在我下面的示例應用程序中),_Tp和_Class :: *將在何處解析?

諸如Tp Class::*類型可以表示指向成員數據的指針指向成員函數的指針,在后一種情況下, Tp將是函數類型。

在你的例子中, _Tp將是函數類型void ()_Class將是foo

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM