0

我有以下课程:

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");

有没有一种优雅的方式来做到这一点?我对模板还很陌生,所以我不知道难度

4

3 回答 3

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
};
于 2012-05-17T20:16:30.347 回答
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();
};

注意,因为基类是不可复制的,派生类也是如此。如果所有清理都可以由基析构函数完成,则可能不需要在派生类中定义析构函数。

于 2012-05-17T18:28:15.867 回答
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
};

断言是首选,因为您的代码将在断言上中断,而在异常情况下,它将在捕获时中断,从而使调试变得稍微困难​​。

于 2012-05-17T18:39:37.923 回答