I'm working in C++11, creating a class template. I wish to optimize certain methods according to the type traits of the template parameter (i.e. float/integer, signed/unsigned etc.). I know this could be achieved by template specialization for each specific combination of traits, but that's too unwieldy.
Instead, I've got something working using the partial template specialization of a dummy struct wrapper (because so far as I'm aware partial specialization only works with structs/classes).
Working example here:
#include<type_traits>
#include<iostream>
template<typename T>
struct A
{
A( T _x ) : x(_x) {}
template<typename U, bool foobar = std::is_signed<T>::value>
struct temp{};
template<typename U>
struct temp<U,true>
{
static constexpr U diff( A const &left, A const &right ) noexcept
{
std::cout << "Signed" << std::endl;
T d = left.x - right.x;
return d * d;
}
};
template<typename U>
struct temp<U,false>
{
static constexpr U diff( A const &left, A const &right ) noexcept
{
std::cout << "Unsigned" << std::endl;
T d = left.x < right.x ? right.x - left.x : left.x - right.x;
return d * d;
}
};
protected:
T x;
};
int main( int argc, char** argv )
{
// Unsigned
A<unsigned int> u1( 10 );
A<unsigned int> u2( 15 );
// Method call
std::cout << A<unsigned int>::temp<unsigned long>::diff( u1, u2 ) << std::endl;
// Signed
A<float> f1( -1.23f );
A<float> f2( 12.3f );
// Method call
std::cout << A<float>::temp<double>::diff( f1, f2 ) << std::endl;
}
Having to dereference the dummy struct is cumbersome from the template user's point of view, so I'd particularly like to improve that, if possible.
My knowledge of C++ is far from encyclopedic, so I'm wondering if there are nicer solutions out there. Preferably C++11 compatible, but I'm curious to hear about alternatives in modern C++ too.
Obviously I have googled this, but it took all my search skills to get the above working.
Thanks in advance.
Aucun commentaire:
Enregistrer un commentaire