Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Частичная специализация методов в шаблоне класса


Автор: jorikdima 23.6.2010, 11:42
Здравствуйте.
Читал, читал про специализацию, так и не осознал, как сделать.
Есть шаблон:
Код

template< class Tp , int Size>
class SomeTpl{
private:
    Tp var1[Size];
public:
    void some_op1();
    void some_op2();
    Tp getVar();
    };

В нем два параметра и это важно, ибо когда нету Size, а просто template< class Tp> то все компилируется.
Есть реализации:
Код

template< class Tp  , int Size>
Tp SomeTpl<Tp, Size>::getVar()
    {
    return var1[0];
    }

template< class Tp , int Size >
void SomeTpl<Tp, Size>::some_op1()
    {
    var1[0] = 1;
    }

template< class Tp , int Size >
void SomeTpl<Tp, Size>::some_op2()
    {
    var1[0] = 2;
    }


template<>
void SomeTpl<int, 6>::some_op1()
    {
    var1[1] = 3;
    }


Тут я попытался переопределить метод some_op1 для Tp являющегося int и для Size=6. Но!!! Я не хочу фиксировать реализацию (или как его там... инстантенацию) для фиксированного Size.  Хочу, чтобы писалось, что то типа
Код

template<class Tp , int Size>
void SomeTpl<int, Size>::some_op1()
    {
    var1[1] = 3;
    }

Но так не компилируется, а выдает кучу ошибок.
Как сделать частичную специализацию в моем случае?
Спасибо.

Автор: azesmcar 23.6.2010, 12:19
Код

#include <iostream>

template< class Tp , int Size>
class SomeTpl{
public:
    void foo()
    {
        std::cout << "A" << std::endl;
    };
};

template<>
void SomeTpl<int, 6>::foo()
{
    std::cout << "B" << std::endl;
}

int main()
{
    SomeTpl<int, 7> t1;
    t1.foo();
    SomeTpl<int, 6> t2;
    t2.foo();
}

?

Автор: jorikdima 23.6.2010, 12:25
Цитата(azesmcar @ 23.6.2010,  12:19)
Код

template<>
void SomeTpl<int, 6>::foo()
{
    std::cout << "B" << std::endl;
}

?

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

Автор: azesmcar 23.6.2010, 12:36
Цитата(jorikdima @  23.6.2010,  12:25 Найти цитируемый пост)
В том то  и дело, что я не хочу переопределять инстантенацию для фиксированного Size, я это проблемой и обозначил. Я хочу чтоб Size оставался параметром шаблона. 

Да, неверно понял вопрос. Тогда надо специализировать весь класс, частичной специализации функций нету.
Код

#include <iostream>

template<class Tp, int Size>
class SomeTpl{
public:
    void foo()
    {
        std::cout << "A" << std::endl;
    };
};

template<int Size>
class SomeTpl<int, Size>{
public:
    void foo()
    {
        std::cout << "B" << std::endl;
    };
};

int main()
{
    SomeTpl<float, 7> t1;
    t1.foo();
    SomeTpl<int, 6> t2;
    t2.foo();
}

Автор: jorikdima 23.6.2010, 14:18
Понял, спасибо. Печально.
В случае специализации класса я обязан переписать вообще все методы класса, или только те, которые зависят от параметров шаблона? Если все вообще, то тут теряется смысл шаблона.
Странно почему нет частичной специализации... что мешало Страуструппу ее ввести?

Автор: azesmcar 23.6.2010, 14:28
Цитата(jorikdima @  23.6.2010,  14:18 Найти цитируемый пост)
В случае специализации класса я обязан переписать вообще все методы класса, или только те, которые зависят от параметров шаблона? Если все вообще, то тут теряется смысл шаблона.

можно выкрутиться наследованием.

как-то так
Код

#include <iostream>

template<class T, int Size>
class SomeTplBase{
public:
    void foo1()
    {
        std::cout << "A" << std::endl;
    };
    void foo2()
    {
        std::cout << "B" << std::endl;
    };
};

template<class T, int Size>
class SomeTpl : public SomeTplBase<T, Size> {};

template<int Size>
class SomeTpl<int, Size> : public SomeTplBase<int, Size> {
public:
    void foo1()
    {
        std::cout << "C" << std::endl;
    };
};

int main()
{
    SomeTpl<float, 7> t1;
    t1.foo1();
    SomeTpl<int, 6> t2;
    t2.foo1();
}


Цитата(jorikdima @  23.6.2010,  14:18 Найти цитируемый пост)
Странно почему нет частичной специализации... что мешало Страуструппу ее ввести? 

Если я правильно помню у Саттера в решении сложных задач описано.

Автор: jorikdima 23.6.2010, 15:15
azesmcar, спасибо. Понял идею.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)