根据
https://gcc.gnu.org/projects/cxx-status.html,g ++版本7,与标记-std=c++1z
一起使用,支持类模板的模板参数推导。
我希望编译以下代码,特别是因为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 ++抱怨&#34; 模板占位符类型&#39; Base&#39;必须后跟一个简单的declarator-id &#34 ;;如果我理解正确,它不会推断出模板参数
很遗憾,因为我想动态决定哪个派生类pt_base
指向哪个(可能是来自类Derived<someType>
或来自类Derived2<someType2>
的对象)。这样,数组或vector<Base *>
可以存储指向各种派生类的对象的指针。
GCC只有experimental support用于C ++ 17而且我无法访问另一个编译器,所以虽然我收到编译错误,但我不确定我的代码是错误的。你怎么看?
我们如何动态地确定pt_base
指向Derived<someType>
或Derived2<someType2>
中的对象(因此可以使用多态)?
答案 0 :(得分:8)
类模板参数推导适用于声明类类型的实例:
Derived d(42);
或者新表达式:
auto p = new Derived(42);
或函数式转换:
foo(Derived(42));
它不能用于声明指针。
您必须提供模板参数,因为您一直都必须这样做。或者,我想:
template <class T> Base<T>* downcast(Base<T>* p) { return p; }
auto pt_base = downcast(new Derived(42));