Можно ли написать специализацию для функции-члена шаблонного класса? - PullRequest
3 голосов
/ 29 июля 2011
template <class T, bool flag>
class A
{
    //...
    void f()
    {
        std::cout << "false" << std::endl;
    }
    //...
};

template<class T>
void A<T, true>::f<T, true>()
{
    std::cout << "true" << std::endl;
}

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

Ответы [ 4 ]

5 голосов
/ 29 июля 2011

Вы не можете специализировать только один метод класса. Обычно вы можете решить это с помощью вложенного класса шаблона на том же T.

template <class T, bool flag>
class A
{
    //...
    template <class Q, bool flag>
    class F_Helper
    {
        void operator()()
        {
            std::cout << "false" << std::endl;
        }
    };

    template <class Q>
    class F_Helper<Q, true>
    {
        void operator()()
        {
            std::cout << "true" << std::endl;
        }
    };

    F_Helper<T> f;
    //...
};

Очевидно, что вам понадобится немного больше шаблонов, если вам нужен доступ к указателю this включающего класса.

2 голосов
/ 29 июля 2011

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

template<>
void A<int, true>::f()
{
    std::cout << "true" << std::endl;
}

То, что вы пытаетесь, недействительно:

template<typename T>
void A<T, true>::f()
{
    std::cout << "true" << std::endl;
}

Частичная специализация члена шаблона класса для конкретных аргументов этого шаблона класса недопустима, поэтому это означает «определить функцию-член« f »частичной специализации A для <T, true>». Поскольку такой частичной специализации нет, компилятор выдаст ошибку.

Если вы не можете предоставить все аргументы, вы можете перегрузить f следующим образом

template <class T, bool flag>
class A
{
    template<typename, bool> struct params { };

    void f()
    {
        f(params<T, flags>());
    }

    template<typename U>
    void f(params<U, true>) {
        std::cout << "true" << std::endl;
    }

    template<typename U, bool flag1>
    void f(params<U, flag1>) {
        std::cout << "dunno" << std::endl;
    }
};
0 голосов
/ 29 июля 2011

Нужно специализировать весь класс:

#include <iostream>

template <class T, bool flag>
class A
{
public:
    void f()
    {
        std::cout << "false" << std::endl;
    }
};

template<class T>
class A<T,true>
{
public:
    void f()
    {
        std::cout << "true" << std::endl;
    }
};

void main()
{
    A<int, false> a;
    a.f();

    A<int, true> b;
    b.f();
}
0 голосов
/ 29 июля 2011

Можно специализировать весь класс шаблона - Идеальная ссылка

#include <iostream>

template <class T, bool flag>
class A
{
    //...
    void f()
    {
        std::cout << "false" << std::endl;
    }
    //...
};

template<class T>
class A<T, true>
{
    //...
    void f()
    {
        std::cout << "true" << std::endl;
    }
    //...
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...