C ++中类模板的模板参数推导17:我做错了吗?

时间:2017-09-06 23:24:00

标签: c++ templates g++ c++17

根据 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>中的对象(因此可以使用多态)?

1 个答案:

答案 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));