我有一个带有重载+运算符的模板类.当我添加两个或两个双打时,这工作正常.如何将它添加到int和double并返回double?
template <class T>
class TemplateTest
{
private:
T x;
public:
TemplateTest<T> operator+(const TemplateTest<T>& t1)const
{
return TemplateTest<T>(x + t1.x);
}
}
in my main function i have
void main()
{
TemplateTest intTt1 = TemplateTest<int>(2);
TemplateTest intTt2 = TemplateTest<int>(4);
TemplateTest doubleTt1 = TemplateTest<double>(2.1d);
TemplateTest doubleTt2 = TemplateTest<double>(2.5d);
std::cout << intTt1 + intTt2 << /n;
std::cout << doubleTt1 + doubleTt2 << /n;
}
Run Code Online (Sandbox Code Playgroud)
我希望能够做到这一点
std::cout << doubleTt1 + intTt2 << /n;
Run Code Online (Sandbox Code Playgroud)
Ste*_*hen 13
这里是龙.你正在进入c ++的部分内容,这可能会导致很多问题发布到StackOverflow :)如果你真的想这样做,那么想想很久很难.
从简单部分开始,您希望允许operator+添加并非总是相同的类型T.从这开始:
template <typename T2>
TemplateTest<T> operator+(const TemplateTest<T2>& rhs) {
return TemplateTest<T>(this->x + rhs.x);
}
Run Code Online (Sandbox Code Playgroud)
请注意,这是模板上T2,以及T.当添加doubleTt1 + intTt2,T会doubleTt1和T2会intTt2.
但这是整个方法的大问题.
现在,当你添加一个double和一个int,你期望什么? 4 + 2.3 = 6.3?还是4 + 2.3 = 6?谁会指望6?你的用户应该,因为你将双重投射到一个int,因此失去了小数部分.有时.取决于首先是哪个操作数.如果用户写了2.3 + 4,他们会得到(如预期的那样?)6.3.困扰的图书馆使悲伤的用户.如何最好地处理?我不知道...
Jam*_*lis 13
斯蒂芬已经对你可能遇到的问题做了很好的解释.您可以为模板的所有实例化的所有可能组合定义重载(因此,您实际上已经为double + double,int + double,double + int等定义了运算符).这可能很快变得难以处理,并且难以跟踪支持哪些组合.
你可能最好使用一个名为的非成员函数Add().这样做的好处是您可以指定返回类型.缺点是您必须指定返回类型.:-)但是,一般情况下,这比自动执行意外转换更好.
template <typename R, typename T, typename U>
TemplateTest<R> Add(const TemplateTest<T>& t, const TemplateTest<U>& u)
{
return TemplateTest<R>(t.x + u.x);
}
Run Code Online (Sandbox Code Playgroud)
调用为:
std::cout << Add<double>(intTt1, doubleTt1) << std::endl;
Run Code Online (Sandbox Code Playgroud)
C++ 0x将添加对许多语言功能的支持,这将使这更简单,并允许您编写合理的operator+重载:
template <typename T, typename U>
auto operator+(const TemplateTest<T>& t, const TemplateTest<U>& u)
-> TemplateTest<decltype(t.x + u.x)>
{
return TemplateTest<decltype(t.x + u.x)>(t.x + u.x);
}
Run Code Online (Sandbox Code Playgroud)
这将确保执行通常的算术转换(整数提升,转换为浮点等),并最终得到预期的结果类型.
您的C++实现可能已经支持这些C++ 0x功能; 你想查阅你正在使用的任何编译器的文档.
我希望能够做到这一点
std :: cout << doubleTt1 + intTt2 <<"\n";
这种情况你可能需要的是类型特征.基本上,这些是包含typedefs的模板类.然后,您可以部分专门化这样的模板来覆盖typedefs.
(这可能有点天真,但它应该得到基本的想法.)
template <typename A, typename B>
struct add_traits
{
typedef A first_summand_t; // <-- (kind of an "identity type")
typedef B second_summand_t; // <-- (ditto; both aren't strictly necessary)
typedef B sum_t; // <-- this is the interesting one!
};
Run Code Online (Sandbox Code Playgroud)
现在你部分专门针对各种组合A和B:
template<>
struct add_traits<int, int>
{
typedef int first_summand_t;
typedef int second_summand_t;
typedef int sum_t; // <-- overrides the general typedef
};
template<>
struct add_traits<int, double>
{
typedef int first_summand_t;
typedef double second_summand_t;
typedef double sum_t; // <-- overrides the general typedef
};
template<>
struct add_traits<double, int>
{
typedef double first_summand_t;
typedef int second_summand_t;
typedef double sum_t; // <-- overrides the general typedef
};
Run Code Online (Sandbox Code Playgroud)
现在你可以编写一个相当通用的添加操作,如下所示:
template <typename A, typename B>
typename add_traits<A,B>::sum_t add(A first_summand, B second_summand)
{
// ...
}
Run Code Online (Sandbox Code Playgroud)
如您所见,您没有指定具体的返回类型; 相反,你让编译器通过add_traits模板类来计算它.一旦编译器为特定add函数生成代码,它将在相应的add_traits类中查找类型,并且由于您提供的部分专用版本,您可以确保将应用某些类型的"组合".
PS:当你想减去无符号数时,同样的技术也会很有用.一个unsigned int减去另一个可能导致一个否定的答案; 结果类型必须是(signed)int.
PPS:根据以下评论进行更正.
| 归档时间: |
|
| 查看次数: |
7275 次 |
| 最近记录: |