I try to create a backpack , a template class that acts as wrapper of another, and make calls to a callable provided in one of its arguments.
I would like the callable to be both a class that supports operator( )
, and a normal function.
All the core of the matter is a single function, void call( )
. As C ++ 11 does not support the specialization of member functions, I have created a template base class, which offer that single function. In the daughter class is where all the necessary functionality will be.
To the point. I tried
#include <iostream>
#include <functional>
template< typename T, typename F, bool IC, bool IF > struct Base;
// Especialización para VOID
template< typename T > struct Base< T, void, false, false > {
void call( const T &, signed ) const { }
};
// F es una clase.
template< typename T, typename F > struct Base< T, F, true, false > {
void call( const T &data, signed inc = 1 ) const {
static F imp{ };
imp( data, inc );
}
};
// ESTO FALLA ESTREPITOSAMENTE.
//
// F es una función
template< typename T, typename F > struct Base< T, F, false, true > {
void call( const T &data, signed inc = 1 ) const {
F( data, inc );
}
};
// Clase real, la que usamos.
template< typename T, typename F = void, bool IC = ::std::is_class< F >::value, bool IF = ::std::is_function< F >::value > struct Test :
public Base< T, F, IC, IF > {
T value;
Test< T, F, IC, IF >( ) : value( ) { Base< T, F, IC, IF >::call( value, 1 ); }
};
// Callable de prueba. Una clase.
struct Counter {
template< typename T > void operator( )( const T &, signed i ) { ::std::cout << "Counter: " << i << "\n"; }
};
// Callable de prueba. Una función no-miembro.
void FCounter( const int &, signed inc ) { ::std::cout << "FCounter: " << inc << "\n"; }
int main( void ) {
Test< int > t1; // CASO 1
Test< int, Counter > t2; // CASO 2
Test< int, FCounter > t3; // CASO 3
//Test< int, []( int, signed i ) { std::cout << "lambda: " << i << "\n"; } > t4;
return 0;
}
Within the main( )
are the current test cases. The 1 and the 2 are passed without problems, but the 3 ...
prog.cc:40:23: error: type / value mismatch at argument 2 in template parameter list for 'template struct Test'
Test < int, FCounter > t3;
prog.cc:40:23: note: expected a type, got 'FCounter'
prog.cc:40:23: error: template argument 3 is invalid
prog.cc:40:23: error: template argument 4 is invalid
And, in an abuse ...
std::function< void( const T &, signed ) >
.