Reputation: 3822
Suppose I have a class that define template arguments like std::function
syntax.
// Class that accept template arguments like std::function
template< class T >
class abstraction;
template< class TAbstract, class ...TDeriveds >
class abstraction< TAbstract(TDeriveds...) >
{
public:
using abstract_component_t = TAbstract;
abstraction()
{
int i = 0;
}
};
// Abstract base class
class base
{
public:
virtual void func() = 0;
};
// Derived class
class derived : public base
{
public:
void func() override
{
}
};
When I use an abstract class as template parameter to this class (abstraction<base(derived)>
) I get these errors:
VC++ 2015.3 error: C2259: 'base': cannot instantiate abstract class
GCC 4.9.2 error: invalid abstract return type 'base'
I want to know is it a bug in compilers or it's forbidden to use abstract types with this syntax?
Link to sample source.
Upvotes: 0
Views: 1360
Reputation: 153955
The template argument TAbstract(TDeriveds...)
is a function type declaring a function taking TDeriveds...
as arguments and returning a TAbstract
by value. When returning by value it is necessary that objects of the value type can be instantiated. Objects of an abstract class cannot be instantiated, i.e., returning them by value is illegal (as is taking them as parameters). The relevant clause is 10.4 [class.abstract] paragraph 3:
An abstract class shall not be used as a parameter type, as a function return type, or as the type of an explicit conversion. ...
You can, however, return abstract base classes by reference:
template< class TAbstract, class ...TDeriveds >
class abstraction< TAbstract&(TDeriveds...) >
// ...
Sadly, that means that users of the class need to mention the &
when using the class.
Upvotes: 3
Reputation: 125
Actually, using TAbstract& (or a pointer type) as a type argument for your class will solve the problem.
The problem is trivial: you cannot return an instance of an abstract class. Instead, you can return a reference or a pointer of type TAbstract.
Upvotes: 1