2

Я хочу создать калькуляторРазъяснения по функции шаблона специализации

template < typename T > 
class Calculator 
{ 
    public : 
    Calculator (void); 
    ~Calculator (void); 

    T add(T a, T b) 
    { 
     return (a + b) ; 
    } 
}; 

Теперь я хочу, чтобы сделать это Caculator добавить строки, так что добавьте («Тим», «Джо») даст мне «TimJoe».

Могу ли я использовать специальную функцию шаблона для достижения этой цели путем внесения необходимых изменений в существующий класс.

ответ

3

Почему вы хотели бы?

Calculator<std::string> a; 
std::cout << a.add("Hello", " world") << std::endl; 

Этот код выводит «Hello world». Это не оптимально (параметры std::string в функции члена add взяты значением), но для специализации не требуется специализация.

EDIT ОК, вы хотите специализации, но вы не можете просто специализировать функцию-член add, потому что функция не является самим шаблоном. Вы можете специализироваться весь класс:

template<> 
class Calculator<std::string> 
{ 
public : 
    Calculator() {} 
    ~Calculator() {} 

    std::string add(const std::string &a, const std::string &b) 
    { 
     // Do std::string specific stuff 
     return a + b ; 
    } 
}; 

Или сделайте шаблон функции в add члена и специализироваться его:

class Calculator 
{ 
public : 
    Calculator() {} 
    ~Calculator() {} 

    template<class T> 
    T add(T a, T b) 
    { 
     return a + b; 
    } 
}; 

template<> 
std::string Calculator::add<std::string>(std::string a, std::string b) 
{ 
    // Do std::string specific stuff 
    return a + b ; 
} 

Со вторым раствором, один Calculator экземпляр будет иметь возможность добавлять int, std::string или что вам нужно (так как это функция add, которая является шаблоном, а не классом Calculator).

+0

@silico, @icecrime, используя STL, я могу это сделать; но я хочу использовать специализированную специализацию –

+0

@Sujay Ghosh: Почему требуется специализация шаблона? Использование 'std :: string' намного меньше, чем создание новой специализации' Calculator '. –

+0

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

4

Если вы используете std::string, то вам не придется иметь дело с шаблоном специализации на всех:

Calculator<std::string> calc; 
std::string result = calc.add("Tim", "Joe"); 
// result contains "TimJoe" 

Это на самом деле делает то, что вы думаете, что делает благодаря «волшебству» из стандартной библиотеки, без необходимости выписывать другой класс.

Я бы, однако изменить свой класс шаблона путем add() принимают параметры по const T&:

template < typename T > 
class Calculator 
{ 
public : 
    Calculator() {}; 
    ~Calculator() {}; 

    // Note that we're taking in parameters by const T& 
    // to avoid copies if instances of T are large. 
    T add(const T& a, const T& b) 
    { 
     return (a + b) ; 
    } 
}; 
1

можно (даже если это не обязательны в этом случае для строки, как уже упомянуто @icecrime и @in силикомарганца)

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

#include <iostream> 
#include <string> 

using namespace std; 

template < typename T > 
class Calculator 
{ 
    public : 
    Calculator() {} 
    ~Calculator() {} 

    T add(const T& a, const T& b); 
}; 

template <typename T> 
T Calculator<T>::add(const T& a, const T& b) 
{ 
    return (a + b); 
} 

template <> 
string Calculator<string>::add(const string& a, const string& b) 
{ 
    return (a + " " + b); 
} 

int main() 
{ 
    Calculator<string> ccs; 
    cout << ccs.add("a", "b") << endl; 

    Calculator<int> cci; 
    cout << cci.add(1, 2); 
} 

выход:

a b 
3 

Обратите внимание, что по-прежнему ведет себя, как и следовало ожидать, так что вы не можете сделать, например, так:

Calculator<int> cci; 
    cout << cci.add("a", "b"); 
+0

Этот код не компилируется .- LNK1169: обнаружен один или несколько символов с несколькими значениями –

+0

На вашем конце должно быть что-то не так. Он работает для меня без жалобы с g ++ -ansi -pedantic -Wall -Wextra, и он также работает на кодепаде (который имеет IIRC те же флаги включены) см. Http://codepad.org/ZS2QJQQV – Palmik