[英]Pointer to Parent Class Member Method
我正在嘗試使以下簡單代碼起作用:
#include <functional>
#include <iostream>
class Parent {
public:
void method(int a) {
std::cout << "Parent::method(" << a << ")" << std::endl;
}
};
class Child : public Parent {
public:
};
template <typename T>
std::function<void()> test(T* v, void(T::* fn)(int)) {
return std::function<void()>([v, fn](){
v->fn(10);
});
}
int main() {
Child c;
std::function<void()> fn = test(&c, &Child::method);
fn();
return 1;
}
但我收到以下錯誤:
note: template argument deduction/substitution failed:
note: deduced conflicting types for parameter 'T' ('Child' and 'Parent')
std::function<void()> fn = test(&c, &Child::method);
如果我將指針更改為 Parent::method,我會遇到同樣的問題。 既然 Child “是”父母,為什么編譯器無法推斷出這個模板?
謝謝!
孩子“是”父母
它是面向對象的意義。 但是模板參數推導主要是關於類型標識。
&Child::method
命名Parent
的成員。 它可以在Child
中訪問,但在Parent
中聲明。 因此,該成員唯一可用的T
扣除項是Parent
。 另一方面,指針推斷T
為Child
。 這里T
的身份不能唯一確定。 所以是扣分失敗。
但是我們仍然可以通過調整來編寫您的 function 模板:
template <class C, class P>
std::function<void()> test(C* v, void(P::* fn)(int)) {
return std::function<void()>([v, fn](){
(v->*fn)(10);
});
}
現在這些類是在它們自己的上下文中推導出來的,而不會影響另一個。 這可能就足夠了(因為(v->*fn)(10)
對於不相關的類來說格式不正確)。 但是可能會進行額外的檢查以使過載sfinae友好。
指針&Child::method
是成員 function 指針,指向Parent
中的方法。 就模板參數推導而言, Child
可以訪問此方法的事實無關緊要。 編譯器看到並根據第一個參數推導出T
參數的Parent
。 同時,它根據第一個參數&c
推導出T
的Child
。 這會發生沖突,您會收到錯誤消息。
您可以通過將 function 模板的第二個參數放在非推導上下文中來解決此問題
template <typename T>
struct I { using type = T; };
template <typename T>
std::function<void()> test(T* v, void(I<T>::type::* fn)(int)) {
// ^________^ T here is not deduced
return std::function<void()>([v, fn](){
(v->*fn)(10);
});
}
現在模板參數推導不受影響,但您仍然可以調用method
,因為它可以從Child
class 訪問。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.