簡體   English   中英

為什么我不能從C ++中的派生類實例調用模板化方法?

[英]Why can't I call a templated method from a derived class instance in C++?

請考慮以下類型:

struct X
{
    static std::string fullyQualifiedName();
};


struct A
{
    template <class T> void foo()
    {
        return foo(T::fullyQualifiedName());
    }

protected:
    virtual void foo(const std::string& name) = 0;
};


struct B : public A
{
protected:
    void foo(const std::string& name);
};

我有一個指向B實例的指針,我試圖像這樣調用foo的模板化版本:

b->foo< X >();

編譯器抱怨:'X':非法使用此類型作為表達式。

另一方面,這段代碼完全可以:

A* a = b;
a->foo< X >();

因此我的問題。

您面臨的問題稱為隱藏。 基本上,語言中的查找規則將以最派生的類型開始,並以它們的方式返回,直到找到適當的符號。 在你的情況下,它會在查看B類時停止,因為它找到void B::foo(const std::string& name) 在那個級別,它將考慮的唯一潛在超載是它所看到的。

為了避免隱藏,您可以帶來所有其他重載,您可以添加using聲明:

struct B : A{
   using A::foo;
   void foo( const std::string & name );
};

不同之處在於查找將處理層次結構,直到找到第一個重載,再次處於B級別,但由於using指令,它還將考慮A可用的任何重載。

或者,您可以保留符號隱藏並通過限定調用強制調度到完全類(請注意,這具有禁用動態調度的副作用,這在這里不是問題,但可能是如果要使用的重載是虛擬的) :

b->A::foo<X>();

暫無
暫無

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

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