2010-11-22 101 views
2

我想创建一个计算器澄清模板功能专业化

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

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

现在,我想使这个计算器中计算出添加字符串,因此加(“添”,“乔”)应给我“TimJoe”。

我可以通过对现有类进行必要的更改来使用模板函数专门化来实现此目的。

回答

3

你为什么要?

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

此代码输出“Hello world”。它不是最优的(std::string成员函数中的add参数是按值取值的),但它不需要专门化工作。

编辑好的,你想要专业化,但你不能只专注于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实例将能够添加intstd::string或任何你需要的东西(因为它的add功能是模板,而不是Calculator类本身)。

+0

@silico,@icecrime,通过使用STL,我可以做到这一点;但我想用模板专业化 – 2010-11-22 10:36:57

+0

@Sujay Ghosh:为什么需要模板专业化?使用'std :: string'远不如创建'Calculator '的新专门化。 – 2010-11-22 10:38:23

+0

我认为第二个解决方案是一个更好的设计。如果有一天我想添加一个自定义类,而不是任何PODS,这将解决我的问题。 – 2010-11-26 07:00:12

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硅片提到它不是在这种情况下,对于字符串neccessary):

#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:找到一个或多个乘法定义的符号 – 2010-11-26 06:56:20

+0

您的结局肯定有问题。它适用于我没有抱怨与g ++ -ansi -pedantic -Wall -Wextra,它也可以在键盘上(它有IIRC打开相同的标志)见http://codepad.org/ZS2QJQQV – Palmik 2010-11-26 13:19:00