C ++ - перегруженный шаблонный метод класса с частичной специализацией этого метода - PullRequest
0 голосов
/ 05 марта 2011

Есть несколько вопросов, уже похожих на этот, уже при переполнении стека, но ничего, что, казалось бы, прямо не отвечало на мой вопрос.Я прошу прощения, если я делаю репост.

Я хотел бы перегрузить несколько методов шаблонного класса (с 2 параметрами шаблона) частичной специализацией шаблона этих методов.Я не смог выяснить правильный синтаксис, и начинаю думать, что это невозможно.Я решил опубликовать здесь, чтобы посмотреть, смогу ли я получить подтверждение.

Пример кода для подражания:

template <typename T, typename U>
class Test
{
public:
    void Set( T t, U u ); 

    T m_T;
    U m_U;
};

// Fully templated method that should be used most of the time
template <typename T, typename U>
inline void Test<T,U>::Set( T t, U u )
{
    m_T=t;
    m_U=u;
}

// Partial specialisation that should only be used when U is a float.
// This generates compile errors
template <typename T>
inline void Test<T,float>::Set( T t, float u )
{
    m_T=t;
    m_U=u+0.5f;
}


int _tmain(int argc, _TCHAR* argv[])
{
    Test<int, int> testOne;    
    int a = 1;
    testOne.Set( a, a );

    Test<int, float> testTwo;    
    float f = 1.f;
    testTwo.Set( a, f );
}

Я знаю, что могу написать частичную специализацию всего класса, ноэто отстой.Возможно ли что-то подобное?

(я использую VS2008) Редактировать: Вот ошибка ошибки компиляции C2244: 'Test :: Set': невозможно сопоставить определение функции с существующим объявлением

Спасибо:)

Ответы [ 3 ]

5 голосов
/ 05 марта 2011

Вы не можете частично специализировать функцию-член без определения частичной специализации самого шаблона класса. Обратите внимание, что частичная специализация шаблона - это ЕДИНСТВЕННЫЙ шаблон, поэтому, когда компилятор видит Test<T, float>, он ожидает частичную специализацию шаблона класса.

-

$ 14.5.4.3 / 1 из C ++ Standard (2003) гласит:

Список параметров шаблона элемент шаблона класса частично специализация должна соответствовать список параметров шаблона класса Частичная специализация шаблона. список аргументов шаблона члена частичный шаблон класса специализация должна соответствовать список аргументов шаблона класса Частичная специализация шаблона. A специализация шаблона класса Отличный шаблон. Члены частичная специализация шаблона класса не связаны с членами Основной шаблон. Шаблон класса члены частичной специализации, которые используются таким образом, что требует определение должно быть определено; определения членов первичного Шаблон никогда не используется в качестве определения для членов шаблона класса частичная специализация. Явный специализация члена класса Частичная специализация шаблона объявлен так же, как явная специализация первичной шаблон.

Тогда сам Стандарт приводит этот пример,

// primary template
template<class T, int I> struct A {
void f();
};
template<class T, int I> void A<T,I>::f() { }

// class template partial specialization
template<class T> struct A<T,2> {
void f();
void g();
void h();
};
// member of class template partial specialization
template<class T> void A<T,2>::g() { }

Надеюсь, цитата из Стандарта вместе с примером хорошо ответят на ваш вопрос.

1 голос
/ 05 марта 2011

Конкретная проблема, которую вы рисуете, проста:

template< class T >
inline T foo( T const& v ) { return v; }

template<>
float foo( float const& v ) { return v+0.5; }

Затем вызовите foo из вашей Test::Set реализации.

Если вам нужна полная общность, аналогичным образом используйте вспомогательный класс со статическими вспомогательными функциями-членами и частично специализируйте этот вспомогательный класс.

Приветствия & hth.,

0 голосов
/ 02 января 2013

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

#include <type_traits>

template <typename T1, typename T2>
class C
{
    void f(T1 t1);
}

template <typename T1, typename T2>
void C<T1, T2>::f(T1 t1)
{
    if (std::is_same<T2, float>::value)
    // Do sth
    else
    // Do sth
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...