Reputation: 1098
According to
https://gcc.gnu.org/projects/cxx-status.html, version 7 of g++, used with flag -std=c++1z
, supports template argument deduction for class templates.
I would expect the following code to compile, especially as Base
is an abstract class, therefore:
1. the compiler knows no instance of Base
can be created;
2. the pointer to base pt_base
points to a clearly defined instance (i.e. Derived<int>{42}
) where the type (int
) is explicit.
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;
}
Yet, it does not compile. G++ complains that "template placeholder type 'Base' must be followed by a simple declarator-id"; if I understand correctly, it does not deduce the template argument.
It's a pity because I would like to dynamically decide which derived class pt_base
points to (could be an object from class Derived<someType>
or from class Derived2<someType2>
). That way, an array or a vector<Base *>
could store pointers to objects of various derived classes.
GCC only has experimental support for C++17 and I don't have access to another compiler, so although I get a compile error I am not sure my code is wrong. What do you think?
And how could we dynamically decide that pt_base
points to an object from either Derived<someType>
or Derived2<someType2>
(so polymorphism can be used)?
Upvotes: 8
Views: 13296
Reputation: 303890
Class template argument deduction works for declaring instances of class types:
Derived d(42);
Or new-expressions:
auto p = new Derived(42);
Or function-style casts:
foo(Derived(42));
It does not work for declaring pointers.
You'll have to simply provide the template arguments as you've always had to. Or, I guess:
template <class T> Base<T>* downcast(Base<T>* p) { return p; }
auto pt_base = downcast(new Derived(42));
Upvotes: 10