struct Report { template< typename Rep, typename T > static std::shared_ptr< Report > get( T t ) { return _get< Rep >( wibble::Preferred(), t ); } template< typename Rep, typename T > static auto _get( wibble::Preferred, T t ) -> decltype( Rep::get( t ) ) { return Rep::get( t ); } template< typename Rep, typename T > static auto _get( wibble::NotPreferred, T t ) -> std::shared_ptr< Report > { return std::make_shared< Rep >( t ); } }; struct SqlReport : Report { #ifndef O_SQL_REPORT template< typename X > static std::shared_ptr< Report > get( X ) { return nullptr; } #endif };