隨附的代碼是我遇到的事情的精簡示例。
首先,這是一個更簡化的版本,可以編譯:
#include <string>
template<typename T>
class Base
{
public:
Base() {}
virtual ~Base() {}
virtual size_t Size (void) const = 0;
};
template<typename T>
class Derived : public virtual Base<T>
{
public:
Derived() {}
virtual ~Derived() {}
virtual size_t Size (void) const override { return 0; }
};
class Impl : public virtual Derived<std::string>,
public virtual Base<char const *>
{
public:
Impl() {}
virtual ~Impl() {}
using Base<char const *>::Size;
virtual size_t Size() const override { return 1; }
};
int
main(int argc, char **argv)
{
Impl oImpl;
}
問題是能夠實施Base<std::string>::Size()以及Base<char const *>::Size().
這個問題有助于達到這個階段。(using宣告是關鍵。)
但是,問題在于,在實際代碼中,我不僅回傳 a size_t,而且回傳嵌套類的實體。
#include <string>
template<typename T>
class Base
{
public:
Base() {}
virtual ~Base() {}
class Contained
{
public:
Contained();
virtual ~Contained();
};
virtual Contained begin (void) const = 0;
};
template<typename T>
class Derived : public virtual Base<T>
{
public:
Derived() {}
virtual ~Derived() {}
virtual typename Base<T>::Contained begin (void) const override
{ return typename Base<T>::Contained(); }
};
class Impl : public virtual Derived<std::string>,
public virtual Base<char const *>
{
public:
Impl() {}
virtual ~Impl() {}
using Base<char const *>::begin;
virtual typename Base<char const *>::Contained begin() const override
{ return typename Base<char const *>::Contained(); }
/* virtual typename Base<char const *>::Contained Base<char const *>::begin() const override
{ return typename Base<char const *>::Contained(); } */
};
int
main(int argc, char **argv)
{
Impl oImpl;
}
不知何故,g /clang 認為這是對 的重新定義Base<std::string>::Size,而不是Base<char const *>::Size——它抱怨協變型別無效。因此using,在第一個代碼示例中運行良好的陳述句在這里無效。
If I try to fully qualify the name, i.e. the commented-out section, g gives me cannot define member function 'Base<const char*>::Size' within 'Impl' (without saying why), and clang gives me non-friend class member 'Size' cannot have a qualified name (which I don't understand at all).
Does anyone know how to override methods from different instances of the same templated base class?
如果有人感興趣,Base是一個通用的“可列舉”類,我正在嘗試創建一個既具有可變介面(即派生自Base<std::string>)和只讀介面(即派生自Base<char const *>)的類,它不會泄漏字串資料存盤在內部。(一般來說,我試圖在 C 中實作 C# 風格的可列舉介面,例如,因此客戶端不必知道底層類是基于串列、向量、集合、映射或其他什么的,只要它的包含的值可以通過非特定介面類列舉...暗示它Contained實際上是一個迭代器類)。
uj5u.com熱心網友回復:
你所擁有的基本上是這樣的:
struct A {
virtual int foo() { return 0;}
};
struct B {
virtual double foo() { return 0;}
};
struct C : A, B {
int foo() override { return 42; }
double foo() override { return 3.14; }
};
哎呀!你不能那樣做。C 中 foo() 的每個覆寫器都會覆寫所有基類中的所有 foo() (相同的引數串列,任何回傳型別)。沒有擺弄using改變。
您需要的本質上是重命名 foo 以便 C 繼承兩個不同名稱的函式。Stroustrup 提出了一種可以做到這一點的技術(我認為在 D&E 中,但不要參考我的話)。
struct A {
virtual int foo() { return 0;}
};
struct B {
virtual double foo() { return 0;}
};
struct AA : A {
virtual int foo1() { return 1; }
// Essentially rename foo to foo1
int foo() override { return foo1(); }
};
struct BB : B {
virtual double foo2() { return 1; }
// Essentially rename foo to foo2
double foo() override { return foo2(); }
};
struct C : AA, BB {
int foo1() override { return 42; }
double foo2() override { return 3.14; }
};
現在 C 仍然有兩個命名的函式foo(),但它們被凍結了。從現在開始,您只操作 foo1 和 foo2。當然,您仍然可以通過 A 和 B 呼叫 foo(),它們將呼叫正確的版本。
所以是的,C::foo 本質上是一個被禁止的名稱。這就是價格。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/433980.html
上一篇:使用模板嵌套型別多載
