簡體   English   中英

模板參數推導指向成員函數的指針?

[英]template argument deduction for pointer to member function?

我正在嘗試構建一個靜態綁定的委托類,其中成員函數在編譯時綁定,從而幫助優化。

我有以下代碼,它完全符合我的要求:

#include <iostream>

namespace thr {

template<typename T, T func>
struct delegate;

template<typename R,
         typename C,
         typename... A,
         R  (C::* mem_fun)(A...)>
struct delegate<R(C::*)(A...), mem_fun>
{ 
  delegate(C* obj_)
    : _obj(obj_)
  {}

  R operator()(A... a)
  {
    return (_obj->*mem_fun)(a...);
  }
 private:
  C* _obj;
};

} // namespace thr

struct foo
{
  double bar(int i, int j)
  { 
    return (double)i / (double)j;
  } 
};

int main()
{
  foo f;

  typedef thr::delegate<decltype(&foo::bar), &foo::bar> cb;      
  cb c(&f);

  std::cout << c(4, 3);
  return 0;
}

但是,使用不是很優雅:

thr::delegate<decltype(&foo::bar), &foo::bar>

我想使用一個函數模板,它推導出模板參數並返回一個委托實例; 一些事情(這段代碼不能編譯):

template<typename C, typename T, T func>
thr::delegate<T, func> bind(T func, C* obj)
{
  return thr::delegate<decltype(func), func>(obj);
} 

這將允許更優雅的語法:

auto cb = bind(&foo::bar, &f);

是否可以在函數模板中推導出非類型參數?

我正在努力實現的目標是什么?

std :: function會有幫助嗎? http://www2.research.att.com/~bs/C++0xFAQ.html#std-function您的示例看起來非常接近。

我認為編譯器提供的STL做了非常可怕的事情,使它順利運行。 在放棄之前,你可能想看一個例子。

編輯:我出去嘗試了你想要完成的事情。 我的結論是編譯錯誤:

  • bind(委托)的返回類型必須將指針命名為member,因為它是您自己的要求。
  • bind應該接受指向成員的指針的名稱(即你的要求)
  • 編譯器要求您不要使用函數參數隱藏模板參數,或者在參數和返回類型中使用名稱。

因此,您的一個要求必須去。

編輯2:我冒昧地改變了你的委托,所以bind可以按你的意願工作。 綁定可能不是你的優先事項。

#include <iostream>

namespace thr {


template<typename C,typename R,typename... A>
struct delegate
{ 
 private:
  C* _obj;
  R(C::*_f)(A...);
  public:
  delegate(C* obj_,R(C::*f)(A...))
    : _obj(obj_),_f(f)
  {}

  R operator()(A... a)
  {
    return (_obj->*_f)(a...);
  }

};

} // namespace thr

template<class C,typename R,typename... A> thr::delegate<C,R,A...> bind(R(C::*f)(A...),C* obj){
    return thr::delegate<C,R,A...>(obj,f);
}

struct foo
{
  double bar(int i, int j)
  { 
    return (double)i / (double)j;
  }
};

int main()
{
  foo f;
  auto c = bind(&foo::bar, &f);
  std::cout << c(4, 6);
  return 0;
}

可以推導出除函數簽名中的類型之外的其他實體,但是函數參數本身不能用作模板參數。

鑒於:

template <size_t I> struct Integral { static size_t const value = I; };

你可以有:

template <size_t N>
Integral<N> foo(char const (&)[N]);

但你不能擁有:

Integral<N> bar(size_t N);

在前一種情況下, N作為數組的大小是參數類型的一部分,在后一種情況下, N是參數本身。 可以注意到,在前一種情況下, N出現在類型簽名的模板參數列表中。

因此,如果您確實需要,則成員指針必須顯示為函數簽名的模板參數列表的一部分。

使用constexpr可能會有一個保存優雅,它可以將常規值轉換為模板參數的常量值:

constexpr size_t fib(size_t N) { return N <= 1 ? 1 : fib(N-1) + fib(N-2); }

Integral<fib(4)> works;

但我不夠精明,不能走那條路......

但是我有一個簡單的問題:為什么你認為這會加快速度? 編譯器非常擅長於常量傳播和內聯,以便能夠在編譯時評估變量的動態類型時內聯調用虛函數。 你確定值得大汗淋漓嗎?

暫無
暫無

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

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