成员变量和构造函数依赖于模板参数

时间:2013-04-08 18:07:41

标签: c++ templates c++11 constructor member

在C ++ 11中,我希望在一个类中有一个成员变量,并且只有在选择了默认模板值时才能初始化它的构造函数(当然,仅适用于支持的类型,如int)。

实现此目的的推荐方法是什么(允许提升)?

类似的东西:

template< int _x = -1 > struct C {
    C() {} // only available if _x != -1
    C( int x ) : x( x ) {} // only available if _x == -1
    // more methods that are common for all _x and refer to _x / x
    private:
    int x; // only available if _x == -1
    // more members that are common for all _x
};

或者换一种方式:对于大小和速度优化,如果选择了另一个值而不是模板默认值,我想使用编译时常量而不是存储在成员变量中的值。

-

这是一个让一切更清晰的例子:

template< int _size = -1 > struct Block {
    Block() { buf = mmap( _size, ... ); } // exists only when size!=-1
    Block( int s ) { buf = mmap( size = s, ... ); } // exists only when size==-1
    ~Block() { munmap( buf, getSize() ); } // should use the correct size
    int getSize() const { return ???; } // gets _size if !=-1, size otherwise
    // other methods that use buf and getSize()
    private:
    void *buf;
    const int size; // only exists for size == -1!
};

部分解决了这个问题:

template< int _x > struct X {
    int getX() const { return _x; }
};
template<> struct X< -1 > {
    X( x ) : x( x ) {}
    int getX() const { return _x; }
    private:
    int x;
};

template< int _x = -1 > struct C : X< _x > {
    C() {} // only available if _x != -1
    C( int x ) : X< _x >( x ) {} // only available if _x == -1
    // more methods that are common for all _x and use this->getX()
};

但是C的构造函数怎么样,还有其他/更好的解决方案?

3 个答案:

答案 0 :(得分:4)

只是一个想法,但也许它会有所帮助:您可以尝试仅使用基类来实现最小的差异,并且&#34;假的&#34;成员变量何时不允许其余的编译:

template< int _x > class B
{
public:
  B() {}
protected:
  static const int x = _x;
};

template<> class B< -1 >
{
public:
  B( int i ) : x( i ) {}
protected:
  int x;
};

template< int _x = -1 >
class C : public B<_x>
{
public:
  using B<_x>::B; // inherit B's ctors

  void f()
  {
    if ( x == ... ) // uses either the member variable x or the static const int x!
  }
};

但正如我所说,这只是一个想法...

答案 1 :(得分:2)

专业化是要走的路:

template <int N> struct C
{
    C(int n) : n_(n) { }
    int n;
};

template <> struct C<-1>
{
    C() { }
    C(int n) : n_(n) { }
    int n;
};

答案 2 :(得分:0)

我和Kerrek SB在这一次。将公共代码(即公共基类中的运行时缓冲区处理)设置为创建两个派生类,一个用于静态大小的缓冲区类,另一个用于动态缓冲区类。或者更好的是,根据common coding guidelines,使用构图。

    class buffer_impl {
    public:
        buffer_impl(int size) : data_ {mmap( size, ... )}, size_ {size} {}
        ~buffer_impl() { munmap( data_, getSize() ); }
        int getSize() const noexcept { return size_; }

        // other buffer routines
        // ...
    private:
        void* data_;
        int size_;
    };

    template <int _size = -1 >
    class buffer {  // static size
    public:
        buffer() : impl_ {_size} {}
        static constexpr int getSize() noexcept { return _size; }
    private:
        buffer_impl impl_;
    };

    template <>
    class buffer<-1> {  // dynamic size
    public:
        buffer(int size) : impl_ {size} {}
        int getSize() const noexcept { return impl_.getSize(); }
    private:
        buffer_impl impl_;
    };