2016-01-08 4 views
2

приводимого следующий фрагмент:специализация шаблонного метода с использованием типа

struct A { 
    template <class T > 
    void doSomething(T t) { 
    std::cout << "doSomething() with " << t << std::endl; 
    } 
}; 
template <class T> 
struct B { 
    T val; 
}; 

Как я могу специализироваться A::doSomething() для шаблона B<T>? Следующая «наивная» попытка не компилируется, но может объяснить, что я хочу добиться:

template<class T> 
void A::doSomething(B<T> t){ 
    std::cout << "doSomething specialized for B: " << t.val << std::endl; 
} 

Это то, что я хочу, чтобы достичь возможно? и если это то, что является синтаксисом?

UPDATE

Читая эту тему я нашел альтернативный способ достижения того, что я хочу: Specialize a template with a template

Поскольку синтаксис не всегда легко с помощью шаблонов, здесь рабочий пример с различными уровнями специализация:

#include <iostream> 
#include <vector> 

namespace details { 
template<class T> struct Impl; 
} 
struct A { 
    template <class T > 
    void doSomething(T t) { 
    details::Impl<T>::f(t); 
    } 
}; 
template <class T> 
struct B { 
    T val; 
}; 
namespace details { 
template<class T> 
struct Impl { 
    static void f(T t){std::cout << "default" << std::endl;} 
}; 
template<template<class> class U, class T> 
struct Impl<U<T> > { 
    static void f(U<T> b){std::cout << "default for U<T>"<< std::endl;} 
}; 
template<> 
void Impl<double>::f(double d) { 
    std::cerr << "doSomething with double " << d << std::endl; 
} 
template<class T> 
struct Impl<B<T> > { 
    static void f(B<T> b); 
}; 
template<class T> 
void Impl<B<T> >::f(B<T> b) { 
    std::cerr << "doSomething with B<T> " << b.val << std::endl; 
} 
template<> 
void Impl<B<int> >::f(B<int> b) { 
    std::cerr << "doSomething with B<int> " << b.val << std::endl; 
} 
} 
template<class T> 
struct C { 
    T toto; 
}; 
int main() { 
    A a; 
    a.doSomething(12.0); 
    B<double> b; 
    b.val = 42.0; 
    a.doSomething(b); 
    B<int> b2; 
    b2.val = 42.0; 
    a.doSomething(b2); 
    C<int> c; 
    a.doSomething(c); 
    std::vector<int> v; 
    a.doSomething(v); 
    return 0; 
} 
+1

Частичная специализация шаблона работает только для классов. См., Например, http://www.gotw.ca/publications/mill17.htm – marom

+0

Функции могут быть полными специалистами. – Rabbid76

+0

Что вы делаете, это перегрузка (что является предпочтительным способом), но вы также должны объявить функцию в классе 'template void doSomething (B )' – 0x499602D2

ответ

2

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

#include <iostream> 

template<class T> struct B { }; 

template<class T> void doSomething(B<T> t) { std::cout << "B\n"; } 

template <class T> void doSomething(T t) { std::cout << "T\n"; } 

int main() { 
    int x; 
    B<double> k; 

    doSomething(x); 
    doSomething(k); 
} 

Выход:

T 
B 
+0

спасибо, но я не могу использовать бесплатную функцию (для примера была упрощена структура A), и это решение налагает на то, что я объявляю два перегруженных варианта в структуре. – Charles

+0

@ Чарльз, да. Ну, у вас нет выбора, кроме как отказаться от перегрузки и использовать частичную специализацию класса. – SergeyA

Смежные вопросы