簡體   English   中英

有一個模板參數,可以是指針類型或非指針類型

[英]Have a template parameter that can be pointer type or non-pointer type

假設我有類似的東西:

template <class T>
void do_something(T t){
  pass_it_somewhere(t);
  t->do_something();
}

現在允許T是指針類型或非指針類型是有用的。 函數do_something(...)基本上可以處理指針和非指針,除了t->do_something() 對於指針,我需要一個->而對於非指針,我需要一個. 訪問成員。

有沒有辦法使T接受指針非指針?

您可以創建一個解除引用機制,如下所示:

template<typename T>
std::enable_if_t<std::is_pointer<T>::value, std::remove_pointer_t<T>&> dereference(T& t) { 
  return *t; 
}

template<typename T>
std::enable_if_t<!std::is_pointer<T>::value, T&> dereference(T& t) {
  return t;
}

並在您的函數中使用它:

template <class T>
void do_something(T t){
  pass_it_somewhere(dereference(t));
  dereference(t).do_something();
}

現場演示

這樣你只需要使用T具體版本。

靈魂1

使用模板專業化:

template <class T>
void do_something(T t){
  pass_it_somewhere(t);
  t.do_something();
}

template <class T>
void do_something(T* t){
  pass_it_somewhere(t);    
  t->do_something();
}

解決方案2

在類T中添加用戶定義的指針運算符:

class A
{
public:
    void do_something() const {}        
    const A* operator->() const { return this; }
};

template <class T>
void do_something(T t){
  pass_it_somewhere(t);      
  t->do_something();
}

另一種解決方案:標簽調度。

namespace detail {
    struct tag_value {};
    struct tag_ptr {};

    template <bool T>  struct dispatch       { using type = tag_value; };
    template <>        struct dispatch<true> { using type = tag_ptr;   };

    template <class T>
    void do_call(T v, tag_value)
    {
      v.call();
    }

    template <class T>
    void do_call(T ptr, tag_ptr)
    {
       ptr->call();
    }
}

然后你的功能變成:

template <class T>
void do_something(T unknown)
{
   do_call(unknown, 
                typename detail::dispatch<std::is_pointer<T>::value>::type{} );

   // found by ADL

}

實例

暫無
暫無

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

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