簡體   English   中英

指向父 Class 成員方法的指針

[英]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 另一方面,指針推斷TChild 這里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推導出TChild 這會發生沖突,您會收到錯誤消息。

您可以通過將 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.

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