2016-06-07 162 views
4

如何將模板指針指向成員函數?以模板非模板參數爲函數模板

通過模板我的意思是以下類型事先不知道:

  • 模板PARAM T是類指針的成員
  • 模板PARAM R是返回類型
  • 可變參數模板PARAM Args...是參數

說明問題的非工作代碼:

template <???> 
void pmf_tparam() {} 

// this works, but it's a function parameter, not a template parameter 
template <class T, typename R, typename... Args> 
void pmf_param(R (T::*pmf)(Args...)) {}  

struct A { 
    void f(int) {} 
}; 

int main() { 
    pmf_tparam<&A::f>(); // What I'm looking for 
    pmf_param(&A::f);  // This works but that's not what I'm looking for 
    return 0; 
} 

是否有可能在C++ 11中實現所需的行爲?

+0

你需要這是一個真正的功能?我已經離開了C++遊戲一段時間了,但是如果你讓你的函數成爲一個類並且重寫'operator()'以便它看起來像一個函數一樣工作呢? – Falmarri

回答

4

我不認爲這個符號是可能的,但。有建議P0127R1使這個表示法成爲可能。該模板將像這樣聲明:

template <auto P> void pmf_tparam(); 
// ... 
pmf_tparam<&S::member>(); 
pmf_tparam<&f>(); 

添加auto非類類型參數的建議被票選入C++工作文件Oulu,結果被評爲成爲CD通向C++ 17也在奧盧。沒有auto類型的非類型參數,你需要提供指針的類型:

template <typename T, T P> void pmf_tparam(); 
// ... 
pmf_tparam<decltype(&S::member), &S::member>(); 
pmf_tparam<decltype(&f), &f>(); 
0

問題是不知道參數的類型,並希望該類型的模板參數。

有了一個額外的decltype(仍然在模板參數),這個工程:

#include <iostream> 
using namespace std; 

template <typename T, T ptr> 
void foo(){ 
    ptr(); 
} 

void noop() { 
    cout << "Hello" << endl; 
} 

int main() { 
    //Here have to use decltype first 
    foo<decltype(&noop), noop>(); 

    return 0; 
} 
1

正如你不是說你真的是在後的功能,最簡單的是:

struct A { 
    void bar() { 
    } 
}; 

template <typename T> 
void foo() { 
    // Here T is void (A::*)() 
} 

int main(void) { 
    foo<decltype(&A::bar)>(); 
} 

但是如果你想要簽名細分,我不知道有直接解決類型的一種方式,但是你可以用一點間接...

struct A { 
    void bar() { 
     std::cout << "Call A" << std::endl;  
    } 
}; 

template <typename R, typename C, typename... Args> 
struct composer { 
    using return_type = R; 
    using class_type = C; 
    using args_seq = std::tuple<Args...>; 
    using pf = R (C::*)(Args...); 
}; 

template <typename C, typename C::pf M> 
struct foo { 
    static_assert(std::is_same<C, composer<void, A>>::value, "not fp"); 

    typename C::return_type call(typename C::class_type& inst) { 
     return (inst.*M)(); 
    } 

    template <typename... Args> 
    typename C::return_type call(typename C::class_type& inst, Args&&... args) { 
     return (inst.*M)(std::forward<Args...>(args...)); 
    } 
}; 

template <class T, typename R, typename... Args> 
constexpr auto compute(R (T::*pmf)(Args...)) { 
    return composer<R, T, Args...>{}; 
} 

int main() { 
    foo<decltype(compute(&A::bar)), &A::bar> f; 
    A a; 
    f.call(a); 
} 

以上步驟S HOULD你是什麼後...

1

你可以做的是

template <template T, T value> 
void pmf_tparam() {} 

然後

pmf_tparam<decltype(&A::f), &A::f>();