在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
的构造函数怎么样,还有其他/更好的解决方案?
答案 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_;
};