我想在擁有派生類的實例的對象內獲取基類的模板類型。下面的代碼片段不起作用,因爲Base和它的ArbitraryType不能通過DerivedString被引用。 (標有感嘆號的行)。然而,它絕對可以從它自己的模板類型(OneOfTheDerivedTypes)中推斷出來。在我的情況下,我打算爲AnotherObject使用定義的模板進行繼承,所以我不想只將返回類型硬編碼爲GetSomethingFromThingy()。獲取模板類型的基類內擁有派生實例的類
// -------------------
// Provided by my API:
// -------------------
template <typename ArbitraryType>
class Base {
virtual void DoSomething(ArbitraryType);
};
template <typename OneOfTheDerivedTypes>
class AnotherObject<OneOfTheDerivedTypes> {
// Other functions that perform useful tasks are here so that
// classes that inherit from AnotherObject need not implement them.
void SomethingMagical();
// A function with a specific return type.
virtual DerivedString::Base::ArbitraryType GetSomethingFromThingy() = 0; /* ! */
protected:
OneOfTheDerivedTypes thingy;
};
// --------------------------------------
// Someone using my API would make these:
// --------------------------------------
class DerivedFloat : public Base<float> {
void DoSomething(float) override;
};
class DerivedString : public Base<string> {
void DoSomething(string) override;
};
class UsefulObject : public AnotherObject<DerivedString> {
// Knows the required return type of GetSomethingFromThingy() without
// needing to specify it as a template. Should throw compile-time error
// if you tried to override with a different return type. In other words,
// forces return type to be string because of use of DerivedString.
string GetSomethingFromThingy() override;
};
一種解決方法是指定稱爲ArbitraryType額外模板ARG如下所示:
template <typename OneOfTheDerivedTypes, typename ArbitraryType>
class AnotherObject<OneOfTheDerivedTypes> {
virtual ArbitraryType GetSomethingFromThingy() = 0;
protected:
OneOfTheDerivedTypes thingy;
};
class UsefulObject<DerivedString, string> : public AnotherObject<DerivedString, string> {
string GetSomethingFromThingy() override;
};
程序員然後必須指定參數,其中OneOfTheDerivedTypes要麼DerivedFloat或DerivedString和ArbitraryType被浮子或串, 分別。不是一個好的解決方案,因爲ArbitraryType完全由OneOfTheDerivedTypes的選擇來指定。
我認爲額外的模板(ArbitraryType在AnotherObject)可以通過其基地在公共職能返回ArbitraryType的一個實例來避免(稱之爲ReturnInstanceOfArbitraryType()),並使用decltype(OneOfTheDerivedTypes :: ReturnInstanceOfArbitraryType())AnotherObject內。這看起來很不雅觀,因爲ReturnInstanceOfArbitraryType()在其他情況下是無用的(並且必須是公共的)。這是一個正確的事情是使用特質類嗎?有更好的解決方案嗎? (仍然得到這些新的C++ 11的東西)。謝謝!
裏面'Base'你可以有'的typedef ArbitratyType TypeOfBase'後來在派生類,你可以用'的TypeOfBase'代替'DerivedString :: Base :: ArbitraryType'在你的第一個示例中。 –
啊,是的。這很好,請隨時在下面回答。它堅持認爲我使用'typename DerivedType :: TypeOfBase',這有點不幸。似乎它應該能夠從它被使用的方式以及它是typedef的事實中知道它是一種類型。我在這裏閱讀更多關於它:http://stackoverflow.com/questions/7923369/when-is-the-typename-keyword-necessary – Chet
使用聲明可以幫助清理typename關鍵字:使用TypeOfBase = typename DerivedType: :TypeOfBase – Chet