我正在尝试使用以下代码,但无法完成它。
有人能看到问题吗?
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.
}
};
以下用法给出了编译错误:
IResourceJob* job = new ResourceJob<int>;
谢谢!
答案 0 :(得分:2)
编译器为任何永远无法实例化的模板提供错误。对于类模板的成员函数(假设您的意思是static_assert
),这是正确的,因此编译器可以为您提供诊断。
您希望条件取决于T
并巧妙地使其在实例化时始终评估为false 。例如
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!");
}
};
由于编译器无法知道用户是否会对always_false
进行专门化(当然,您不会这样做),因此无法再提前拒绝该模板。
我还怀疑您是否想将static_assert放入execute
,因为您的错误消息表明ResourceJob
整体需要专门化。因此,将static_assert
放在成员函数之外的类体中。如果您不希望用户专门化整个模板,而只需要成员函数,则用户需要说
// 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() {
}
这将提供execute
的替代定义,如果T
为int
,模板将使用该定义。
答案 1 :(得分:1)
IResourceJob* job = new ResourceJob<int>;
失败,因为类ResourceJob<int>
不是来自IResourceJob
。
代码应为
template<>
class ResourceJob<int> : public IResourceJob
{
public:
void execute()
{
// test.
}
};
答案 2 :(得分:1)
您还需要派生模板专业化,如:
template<>
class ResourceJob<int> : public IResourceJob
{ /* ... */ };