消除模板不需要的大小写 class
Eliminating the unwanted case for a template class
我正在使用模板 class 类型数据类型作为 class 方法的参数。在那种方法中,我正在计算参数的差异并将其打印出来。这只是实际项目中的示例代码。
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()
应该打印一个语句(比如 "String datatype is not allowed")和 return 到调用函数。我可以在 calcDifference()
ONLY 中进行更改,因为在实际项目中我无法控制调用函数。我认为异常处理在这种情况下无济于事,因为它有助于捕获运行时错误,但在这种情况下,我收到编译时错误,因为调用函数试图传递字符串(模板 T 是字符串)。
PS: 我不能在这个结构中做任何改变,这意味着我什至不能改变参数的数量等。我只能在方法内部进行改变calcDifference()
.
行
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);
}
};
我认为有一个非常简单的解决方案:模板专业化。
只需为 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;
}
每当您在 string
上调用 calcDifference
时,都会优先使用专用版本的实现。我已经完成了您的示例 here。这样,您不需要更改任何调用函数。
进一步说明:我添加了一些 const &
用于处理模板参数。这通常是一种很好的做法,但对于模板来说是必不可少的:一些通过的 T
可能很大,因此仅仅为了计算差异而进行复制的成本很高。
我正在使用模板 class 类型数据类型作为 class 方法的参数。在那种方法中,我正在计算参数的差异并将其打印出来。这只是实际项目中的示例代码。
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()
应该打印一个语句(比如 "String datatype is not allowed")和 return 到调用函数。我可以在 calcDifference()
ONLY 中进行更改,因为在实际项目中我无法控制调用函数。我认为异常处理在这种情况下无济于事,因为它有助于捕获运行时错误,但在这种情况下,我收到编译时错误,因为调用函数试图传递字符串(模板 T 是字符串)。
PS: 我不能在这个结构中做任何改变,这意味着我什至不能改变参数的数量等。我只能在方法内部进行改变calcDifference()
.
行
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);
}
};
我认为有一个非常简单的解决方案:模板专业化。
只需为 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;
}
每当您在 string
上调用 calcDifference
时,都会优先使用专用版本的实现。我已经完成了您的示例 here。这样,您不需要更改任何调用函数。
进一步说明:我添加了一些 const &
用于处理模板参数。这通常是一种很好的做法,但对于模板来说是必不可少的:一些通过的 T
可能很大,因此仅仅为了计算差异而进行复制的成本很高。