In C++11, I'd like to have a member variable in a class and a constructor for its initialization only if its default template value was chosen (only for supported types like int, of course).
What are recommended ways to achieve this (boost allowed)?
Something like:
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
};
Or, put in another way: For size and speed optimization, I would like to use a compile time constant instead of a value stored in a member variable if another value than the template default was chosen.
--
Here is an example to make everything clearer:
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!
};
This solves it partially:
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()
};
But what about the constructors of C
, and are other / nicer solutions available?
Just an idea, but maybe it helps: You could try to use a base class only for the minimal differences and "fake" the member variable for when it's not there to allow the rest to compile:
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!
}
};
but as I said, it's just an idea...
Specialization is the way to go:
template <int N> struct C
{
C(int n) : n_(n) { }
int n;
};
template <> struct C<-1>
{
C() { }
C(int n) : n_(n) { }
int n;
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With