Специализация шаблонной функции C ++

Я должен реализовать функцию non-member isHomogenous (Triple Triple) для класса шаблона, определенного как:

template <typename T1, typename T2, typename T3>
class Triple
{
public:
Triple()
{ }
Triple(const T1 &a, const T2 &b, const T3 &c) : a(a), b(b), c(c)
{ }
...

Функция isHomogenous должна возвращать значение bool, указывающее, относятся ли все три значения в тройке параметров к одному типу. Я пытался:

template <typename T> bool isHomogenous(Triple<T, T, T> triple) {
return true;
}

template <typename T1, typename T2, typename T3> bool isHomogenous(Triple<T1, T2, T3> triple) {
return false;
}

Это не работает, вы можете намекнуть мне на решение?

1

Решение

Шаблон функции не может быть частично специализированным.

Одна альтернатива — определить ее как статическую функцию-член (или, в вашем случае, просто как значение!) Шаблона класса, а затем просто предоставить обычную функцию-оболочку шаблона, как…

#include <type_traits>

template< class T1, class T2, class T3 >
struct Blah {};

namespace detail {
template< class T1, class T2, class T3 >
struct IsHomogenous { static bool const yes = false; };

template< class T >
struct IsHomogenous< T, T, T > { static bool const yes = true; };
}  // namespace detail

template< class T1, class T2, class T3 >
bool isHomogenous( Blah< T1, T2, T3 > )
{
return detail::IsHomogenous< T1, T2, T3 >::yes;
}

#include <iostream>
int main()
{
using namespace std;
wcout << boolalpha
<< isHomogenous( Blah< double, char, void >() ) << " "<< isHomogenous( Blah< int, int, int >() )
<< endl;
}

и другой способ заключается в использовании C ++ 11 std::is_same:

#include <type_traits>

template< class T1, class T2, class T3 >
struct Blah {};

template< class T1, class T2, class T3 >
bool isHomogenous( Blah< T1, T2, T3 > )
{
using std::is_same;
return is_same< T1, T2 >::value && is_same< T2, T3 >::value;
}

#include <iostream>
int main()
{
using namespace std;
wcout << boolalpha
<< isHomogenous( Blah< double, char, void >() ) << " "<< isHomogenous( Blah< int, int, int >() )
<< endl;
}
8

Другие решения

Вы не можете специализировать шаблонную функцию, когда вы добавляете специализацию, специализированная функция фактически добавляется в набор перегрузки, так что она такая же, как перегрузка, и для выбора, какую функцию использовать для вызова правил разрешения перегрузки.

Если вы действительно хотите специализировать шаблонную функцию, делегируйте структуру или класс со статическим членом и вместо этого специализируйте шаблонную структуру:

template <typename T>
struct handler
{
static void perform(T& );
};

template <>
struct handler<int>
{
static void perform(int) { doStuff(); }
};

А вот и глобальная функция (которую вы хотите специализировать):

template <typename T>
void function (T& v)
{
handler<T>::perform(v);
}

Надеюсь это поможет.

2

Вы можете частично специализировать класс с помощью функтора, который будет возвращать true или false. (или статический член, что угодно):

template< class T1, class T2, class T3 >
class Blah {};

template< class T>
struct isHomogenous
{
const bool operator()() { return false; }
};

template< template <typename,typename,typename> class T, class T1, class T2, class T3 >
struct isHomogenous<T<T1,T2,T3>>
{
const bool operator()() { return false; }
};template< template <typename,typename,typename> class T, class T1>
struct isHomogenous<T<T1,T1,T1>>
{
const bool operator()() { return true; }
};

std::cout << isHomogenous< Blah<double, char, void> >()() << " "<< isHomogenous< Blah<int, int, int> >()();
0
По вопросам рекламы [email protected]