C++从函数返回两个模板参数中更精确的一个?
我很好奇是否有任何方法可以在 C++ 中做到这一点。假设我有一个模板化向量类:
template <typename T>
class vector {
public:
vector(T a, T b, T c) : x(a), y(b), z(c) {}
T x,y,z;
};
然后我有一个模板化加法运算符:
template <typename A, typename B>
vector<A> operator +(const vector<A> &a, const vector<B> &b) {
return vector<A>(a.x+b.x, a.y+b.y, a.z+b.z);
}
我很好奇是否可以修改该运算符,以便结果是两种类型 A 和 B 中更精确的一个,除了手动专门化它之外。
例如:
vector<float> + vector<double> would produce a vector<double>,
vector<long double> + vector<float> would produce a vector<long double>
我的猜测是 C++ 中没有对此的自动支持,但我想我应该问一下。
I'm curious if there's any way to do this in C++. Let's say I have a templated vector class:
template <typename T>
class vector {
public:
vector(T a, T b, T c) : x(a), y(b), z(c) {}
T x,y,z;
};
And then I have a templated addition operator:
template <typename A, typename B>
vector<A> operator +(const vector<A> &a, const vector<B> &b) {
return vector<A>(a.x+b.x, a.y+b.y, a.z+b.z);
}
I'm curious if it's possible to modify that operator so the result is whichever of the two types A and B is more precise, aside from manually specializing it.
For example:
vector<float> + vector<double> would produce a vector<double>,
vector<long double> + vector<float> would produce a vector<long double>
My guess would be that there's no automatic support for this in C++, but I thought I'd ask.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
没有任何库形式的内置支持,但您可以使用条件 (
?:
) 运算符来完成此操作。在回复另一个答案时,Johannes Schaub 发布了 a
promote
template 很好地包装了逻辑。使用模板,您应该能够编写:There isn't any built-in support in the form of a library, but you can accomplish this using the conditional (
?:
) operator.In reply to another answer, Johannes Schaub posted a
promote<T, U>
template that wraps the logic up quite nicely. With the template, you should be able to write:在 C++0x 中,您可以说:
在 C++03 中,您需要自己定义所有组合,尽管您可以通过可重用的 op_traits 方案来完成,该方案可应用于各种不同的运营商。 James McNellis 在他的回答
in C++0x, you could say:
In C++03, you need to define all the combinations yourself, although you can do it in a reusable
op_traits
scheme that can be applied to a variety of different operators. James McNellis provides some details on this in his answerAndrei Alexandrescu 在他 2001 年 4 月 1 日的 DDJ 文章 通用:最小和最大 Redivivus。
总之,总体问题非常复杂。
Andrei 使用了 80 行支持代码,这些代码又依赖于 Loki 库。
干杯&哈,.
Andrei Alexandrescu discussed this in his 1st April 2001 DDJ article Generic: Min and Max Redivivus.
In short, the general problem is very complex.
Andrei used 80 lines of support code, those lines in turn relying on the Loki library.
Cheers & hth,.
有一种相对简单的方法可以使用模板专业化来做到这一点
然后您使用它来创建一个HigherPrecisionType,
但我不确定如何比较这些以获得专业化中的typedef到适当的类型。但我希望你明白
There is a relatively easy way to do this with template specializations
Then you use this to create a HigherPrecisionType
I'm not sure how to compare these to get a typedef in the specialization to the appropiate type though. But i hope you get the idea
模式“类型选择”(在“现代 C++ 设计”中阅读)在这里可能很有用。
Pattern "Type Selection" (read about it in "Modern C++ Design") can be useful here.
我选择尺寸更大的类型:
帮助模板:
现在使用它:
请参阅在线演示: http://www. ideone.com/PGyA8
I'm choosing the type greater in size:
Helper templates:
Now use it:
See online demonstration : http://www.ideone.com/PGyA8
您可以通过使用函数重载来实现您的目标。这意味着除了通用之外:
您还声明了特定类型的重载,然后使用这些重载而不是通用制造的重载:
您的另一个选择是在向量模板上实现所需类型的转换运算符。让浮点向量能够通过运算符返回双精度向量。
You can accomplish your goal somewhat by using function overloading. Meaning that in addition to the generic:
you also declare overloads for specific types, and these then get used rather than generically manufactured ones:
Your other option would be to implement conversion operators on your vector template for the types required. Have a float vector be able to return a double vector via an operator.
是的。这是 C++03 方法:
显然,如果可以的话,您可以使用 C++0x 方法来实现。
Yep. Here's the C++03 method:
Obviously you do it the C++0x way if you can.
C++11 引入了
std::common_type
,并且 C++14 引入了std::common_type_t
因此您现在应该能够编写:C++11 introduced
std::common_type
, and C++14 introducedstd::common_type_t
so you should now be able to write:你永远无法完成这个:
vector; + 矢量<双>会产生一个向量
,而无需大量欺骗或返回指向您自己设计的某些小玩意的指针,因为
operator+
必须返回编译时已知的类型。您要求返回在运行时确定的类型。You'll never be able to accomplish this:
vector<float> + vector<double> would produce a vector<double>
without massive trickery or returning a pointer to some gizmo of your own design because
operator+
must return a type that is known at compile-time. You are asking to return a type that is determined at run-time.