Специализация члена шаблона C ++ - это ограничение компилятора? - PullRequest
4 голосов
/ 10 июня 2010

Можно ли выполнить такую ​​специализацию?
Если да, то как?

Соответствующая специализация помечена // ЭТА СПЕЦИАЛИЗАЦИЯ НЕ СОПОЛНИТСЯ Я использовал VS2008, VS2010, gcc 4.4.3 и ни один не может скомпилировать это.

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

#include<iostream>
#include<string>

using namespace std;

template <typename ALPHA>
class klass{
    public:
        template <typename BETA>
        void func(BETA B);
};

template <typename ALPHA> template <typename BETA>
void klass<ALPHA>::func(BETA B){
    cout << "I AM A BETA FUNC: " << B <<endl;
}

//THIS SPECIALIZATION WILL NOT COMPILE
template <typename ALPHA> template <>
void klass<ALPHA>::func(string B){
    cout << "I AM A SPECIAL BETA FUNC: " << B <<endl;
}

int main(){
    klass<string> k;
    k.func(1);
    k.func("hello");
    return 0;
}

Ответы [ 2 ]

6 голосов
/ 10 июня 2010

Просто сделайте string версию func обычной не-шаблонной функцией-членом, которая перегружается версией шаблона:

#include<iostream>
#include<string>

using namespace std;

template <typename ALPHA>
class klass{
    public:
        template <typename BETA>
        void func(BETA B);
        void func(string b);
};

template <typename ALPHA> template <typename BETA>
void klass<ALPHA>::func(BETA B){
    cout << "I AM A BETA FUNC: " << B <<endl;
}

template <typename ALPHA>
void klass<ALPHA>::func(string B){
    cout << "I AM A SPECIAL BETA FUNC: " << B <<endl;
}

int main(){
    klass<string> k;
    k.func(1);
    k.func("hello");
    return 0;
}

В дополнение к компиляции, здесь есть еще одно преимущество:получит более интуитивное поведение.См. «Почему бы не специализировать шаблоны функций?»из GOTW .

Редактировать: Чтобы прямо ответить на ваш исходный вопрос, нет, это не ограничение компилятора, это то, что запрещено стандартом C ++.

Стандарт C ++, 14.7.3 / 18, говорит (частично):

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

Это означает, что, поскольку klass является шаблоном, вы не можете специализировать klass::func, не специализируя также klass.

3 голосов
/ 10 июня 2010

Чтобы ответить на вопрос, который вы задаете в заголовке: нет, это не ограничение компилятора.Это ограничение языка.В C ++ для явной специализации вложенного шаблона (будь то шаблон класса или шаблон функции-члена) необходимо также явно специализовать вложенный шаблон.

Вы пытаетесь явно специализовать вложенный шаблон без специализациивмещающий шаблон.Это не скомпилируется.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...