我有以下课程:
template <typename T>
class Fixed2DContainer {
T* ptr;
public:
const int total_cols;
const int total_rows;
Fixed2DContainer(int cols, int rows);
T& operator()(int col_n, int row_n);
~Fixed2DContainer();
private : //disallow copy
Fixed2DContainer& operator=(const Fixed2DContainer&);
Fixed2DContainer operator()(const Fixed2DContainer&);
};
现在我想将这个模板专门用于某个类,这样唯一的变化就是我可以拥有另一个构造函数。 基本上我希望能够做到:
Fixed2DContainer<Image>("filename.jpg");
有一种优雅的方式吗?我对模板很新,所以我不知道难度
答案 0 :(得分:3)
如果你的编译器支持它,那么C ++ 11有继承构造函数,几乎可以让你到达你想要的位置:
template <typename T>
class Base {}; // has all the implementation
template <typename T>
class Template {
using Base::Base;
//Template() = delete; // You might need this if you don't want
// the default constructor
};
template <>
class Template<int> {
using Base::Base;
Template( std::string const & x ) {}
//Template() = delete; // You might need this if you don't want
// the default constructor
};
答案 1 :(得分:1)
这是我在之前评论中的意思的一个简单例子......
template <typename T>
class Fixed2DContainerBase {
T* ptr;
public:
const int total_cols;
const int total_rows;
Fixed2DContainerBase(int cols, int rows);
T& operator()(int col_n, int row_n);
~Fixed2DContainerBase();
private : //disallow copy
Fixed2DContainerBase& operator=(const Fixed2DContainerBase&);
Fixed2DContainerBase(const Fixed2DContainerBase&);
};
// primary template
template <typename T>
class Fixed2DContainer : public Fixed2DContainerBase<T> {
Fixed2DContainer(int cols, int rows);
~Fixed2DContainer();
};
// explicit specialization
template <>
class Fixed2DContainer<Image> : public Fixed2DContainerBase<Image> {
Fixed2DContainer(int cols, int rows);
Fixed2DContainer(const std::string&);
~Fixed2DContainer();
};
N.B。因为基类是不可复制的,派生类也是如此。如果所有清理都可以由基础析构函数完成,则可能没有必要在派生类中定义析构函数。
答案 2 :(得分:0)
我自己也遇到过同样的问题。不幸的是,每个构造函数都必须存在于通用模板中。您可以避免人们在运行时使用错误的构造函数;
template <typename T>
class Fixed2DContainer {
// omitted
Fixed2DContainer(string fileName)
{
// Do not allow construction of Fixed2DContainer with
// string argument in general case
ASSERT(false);
// or
throw new ExceptionType("Not implemented");
}
// omitted
};
template<>
class Fixed2DContainer<Image> {
// omitted
Fixed2DContainer(string fileName)
{
// Actual construction code
}
// omitted
};
断言是首选,因为你的代码会在断言上中断,而在异常情况下它会在catch上断开,使得调试稍微困难。