Reputation: 1490
I'm trying to use the following code, but can't get it to complete.
Can anyone see the problem?
class IResourceJob
{
public:
virtual ~IResourceJob() {}
virtual void execute() = 0;
};
template<typename T>
class ResourceJob : public IResourceJob
{
public:
void execute()
{
static_assert(false, "Specialised ResourceJob<T> not defined!");
}
};
template<>
class ResourceJob<int>
{
public:
void execute()
{
// test.
}
};
The following usage gives a compile error:
IResourceJob* job = new ResourceJob<int>;
Thanks!
Upvotes: 1
Views: 845
Reputation: 506915
The compiler gives an error for any template that can never be instantiated. For your member function of the class template (i assume you mean static_assert
), that is true, so the compiler is in right to give you a diagnostic.
You want to make the condition depend on T
and cleverly make it always evaluate to false when instantiated. For example like
template<typename T>
struct always_false : std::false_type {};
template<typename T>
class ResourceJob : public IResourceJob
{
public:
void execute()
{
static_assert(always_false<T>::value,
"Specialised ResourceJob<T> not defined!");
}
};
Since the compiler cannot know whether the user will put a specialization of always_false
(which you won't, of course), it cannot early-reject the template anymore.
I also doubt that you wanted to put the static_assert into execute
, since your error message indicates that ResourceJob
as a whole needs to be specialized. So put the static_assert
outside of the member function into the class body. If you don't want the user to specialize the whole template, but only the member function, the user instead needs to say
// either "inline" and in the header, or not "inline" and in the .cpp file, but then
// put this into the header: template<> void ResourceJob<int>::execute();
template<> inline void ResourceJob<int>::execute() {
}
This will provide an alternative definition of execute
which will be used by the template if T
is int
.
Upvotes: 2
Reputation: 10096
You need to derive the template specialization as well, as in:
template<>
class ResourceJob<int> : public IResourceJob
{ /* ... */ };
Upvotes: 1
Reputation: 21368
IResourceJob* job = new ResourceJob<int>;
fails because the class ResourceJob<int>
is not derived from from IResourceJob
.
The code should be
template<>
class ResourceJob<int> : public IResourceJob
{
public:
void execute()
{
// test.
}
};
Upvotes: 1