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)?
Template argument deduction is used in declarations of functions, when deducing the meaning of the auto specifier in the function's return type, from the return statement.
A template argument for a template template parameter is the name of a class template. When the compiler tries to find a template to match the template template argument, it only considers primary class templates. (A primary template is the template that is being specialized.)
Can there be more than one argument to templates? Yes, like normal parameters, we can pass more than one data type as arguments to templates.
Template classes and functions can make use of another kind of template parameter known as a non-type parameter. A template non-type parameter is a template parameter where the type of the parameter is predefined and is substituted for a constexpr value passed in as an argument.
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));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With