消除模板类的不必要情况

时间:2015-09-26 21:44:15

标签: c++ template-classes

我使用模板类类型数据类型作为类方法的参数。在那个方法中,我正在计算参数的差异并打印它。这只是实际项目的示例代码。

Header.h

#ifndef Header_h
#define Header_h

#include <iostream>
#include "string.h"

template <class T>
class Student
{
public:
    Student(T);
    void calcDifference(int idx, T val1, T val2);

};
#endif

的main.cpp

#include <iostream>
#include "Header.h"

using namespace std;

template <class T>
void Student<T>::calcDifference(int idx, T val1, T val2)
{
    T difference  = val1 - val2;
    cout<<"\nDifference values: "<<difference<<endl;

}

template <class T>
Student<T>::Student(T)
{
    cout<<"constructor  called";
}


int main(int argc, const char * argv[])
{

    Student<int> oStudent(10);
    oStudent.calcDifference(1, 12, 10);


    //THIS FOLLOWING OBJECT CREATES ERROR BECAUSE IT IS TRYING TO PASS STRING TYPE
    Student<string> o2_Student("hi");
    o2_Student.calcDifference(1, "aaa", "aa");

    return 0;
}

问题:因为,我正在尝试计算calcDifference()内的参数之间的差异,main()中试图传递字符串的第二个对象会产生问题。这是因为差异操作不能在字符串上执行(至少直接)。

错误: /Users/siddharth/coding/cplusplus/xCode/CPPCodes/InterviewTest/InterviewTest/main.cpp:9:26: Invalid operands to binary expression ('std::__1::basic_string<char>' and 'std::__1::basic_string<char>')

我需要的是什么:我希望代码保持通用(对于我无法实际更改的调用函数)。我想找到一些解决方案,以便我不会得到这个编译器错误,如果传递的参数是字符串类型,那么calcDifference()应该打印一个语句(如&#34; String数据类型不是允许&#34;)并返回调用函数。我可以在calcDifference() 仅限内进行更改,因为在实际项目中我无法控制调用函数。我认为异常处理在这种情况下无法帮助,因为它有助于捕获运行时错误,但在这种情况下,我得到编译时错误,因为调用函数正在尝试传递字符串(模板T是字符串)。

PS:我无法对此结构进行任何更改,这意味着我甚至无法更改参数的数量等。我只能在方法calcDifference()内进行更改。

2 个答案:

答案 0 :(得分:1)

该行

T difference  = val1 - val2;
如果没有为类型定义val1 - val2,则

是一个问题。 T = std::string就是这种情况。这就是编译器抱怨的内容。

解决此问题的一种方法是使用帮助程序struct模板,该模板适用于使用通用逻辑的大多数类型,但允许您将其专门用于未定义val1 - val2的类型。

定义帮助器struct

template <typename T> struct difference
{
    T operator()(T val1, T val2) const { return val1 - val2; }
};

而不是使用

T difference  = val1 - val2;

使用

T diff  = difference<T>()(val1, val2);

difference专门std::string

template <> struct difference<std::string>
{
    std::string operator()(std::string const& val1,
                           std::string const& val2) const
    {
       // Figure what it means to compute the difference
       // between two strings for your application.
        return stringDifference(val1, val2);
    }
};

答案 1 :(得分:0)

我认为有一个非常简单的解决方案:模板专业化。

只需为T beeing string添加以下差异方法专长:

template <>
void Student<string>::calcDifference(
    int idx, string const & val1, string const & val2)
{
    cout << "Computing string difference (" << val1 << " - " << val2 
         << ") is undefined!" << endl;
}

每当您在calcDifference上调用string时,都会优先使用该实现的专用版本,因此会使用该版本。我已经完成了您的示例here。这样,您就不需要更改任何调用函数。

进一步说明:我已经添加了一些const &来处理模板参数。这是一般的好习惯,但对于模板来说是必不可少的:一些传递T可能是巨大的,因此复制起来只是为了计算差异。