根據 https://gcc.gnu.org/projects/cxx-status.html,g ++的版本7與標記-std=c++1z
一起使用,支持類模板的模板參數推導。C++中類模板的模板參數推導17:我做錯了嗎?
我希望下面的代碼進行編譯,特別是作爲Base
是一個抽象類,因此:
1.編譯器知道沒有的Base
實例可被創建的;
2.指向基地pt_base
的指針指向明確定義的實例(即Derived<int>{42}
),其中類型(int
)是明確的。
template<typename ValueType>
class Base {
public:
virtual ValueType getValue() = 0;
};
template<typename ValueType>
class Derived : public Base<ValueType>{
public:
Derived(ValueType argt){ value = argt; }
virtual ValueType getValue(){ return value; }
ValueType value;
};
int main(){
Base *pt_base = new(Derived<int>{42}); // *ERROR*
delete pt_base;
}
然而,它does not compile。 G ++抱怨「模板佔位符類型」Base「後面必須跟一個簡單的聲明符號」;如果我理解正確,它不會推導出模板參數。
很遺憾,因爲我想動態地決定哪個派生類pt_base
指向(可能是來自類Derived<someType>
或類Derived2<someType2>
的對象)。這樣,數組或vector<Base *>
可以存儲指向各種派生類的對象的指針。
對於C++ 17,GCC只有experimental support,並且我沒有訪問其他編譯器的權限,所以儘管我收到編譯錯誤,但我不確定我的代碼是否有錯。你怎麼看?
我們如何動態地決定pt_base
指向Derived<someType>
或Derived2<someType2>
(因此可以使用多態性)的對象?
該錯誤消息聲明'Base * pt_base'中的'*'是不允許的。 '* pt_base'是一個_declarator_,但不是_declarator-id_(比如一個未修飾的標識符)。不過,我無法在N4687的任何地方找到這條規則。 – aschepler
@aschepler演繹規則只是在某些地方進行。 [原始提案](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0091r3.html)明確排除了諸如指針,函數和引用之類的內容。 – Barry
此外,模板類扣除發生在編譯時。在你被允許編寫'Base'的情況下,編譯器會決定它是否實際上意味着'Base'或其他什麼。 'Base'不是一種類型。因此,在運行時,您不能在「派生的」或「派生的」上有單個變量點,除非它們實際上都繼承了一些常見類型。您可能需要一個'std :: any'或'std :: variant'作爲其''getValue()'的返回類型。 –
aschepler