【问题标题】:Template - class that uses int, short or float when necessary模板 - 必要时使用 int、short 或 float 的类
【发布时间】:2026-01-23 10:45:01
【问题描述】:

我想编写一个类来管理欧几里得向量并使用 short、int、long 或 float 存储其初始点。我想创建一个这样的模板:

    template<class unit> class EVector
{
private:
    unit x;
    unit y;
public:
    EVector();
    setX();
    setY();
};

所以用户创建了一个 EVector 来选择合适的原始类型。但是如何实现不同类之间的操作,例如

EVector<int> a;
EVector<float> b;

EVector<double> c;

c = a + b;  

operator= 将复制坐标,operator+ 添加它们。

【问题讨论】:

标签: c++


【解决方案1】:

另外,你可以使用我的promote实现:

template<typename A, typename B> 
EVector<typename promote<A, B>::type>
operator +(EVector<A> const& a, EVector<B> const& b) {
  EVector<typename promote<A, B>::type> ev;
  ev.setX(a.getX() + b.getX());
  ev.setY(a.getY() + b.getY());
  return ev;
}

例如,对于 doubleint 类型,它将产生 double

【讨论】:

  • 所以这个解决方案不会考虑所有的转化,只考虑促销。不确定这是否是 OP 想要的。不过,我喜欢促进实施,所以,这是我的 +1 ;)
  • @Armen ?: 所做的所有转换,如果我没记错的话,这归结为所有转换 :) 例如 char*std::string 也会起作用,即使那不是任何形式的推广。 promote 这个名字也许可以重命名。感谢您的 +1 :)
  • 如果它适用于所有转换,那么当一个简单的模板化复制构造函数和复制分配可以完成时,还需要这样可怕的代码吗?
  • @Armen 我很想知道您将如何使用模板构造函数编写 operator+ :)
  • 我只需编写一个简单的运算符 + ,其中一个操作数将通过构造函数转换为另一个。
【解决方案2】:

U 可转换为T 时,您希望启用从EVector&lt;U&gt;EVector&lt;T&gt; 的分配(和复制构造)

template<class T>
class EVector
{
   template<class U>
   EVector(EVector<U> const & rhs)
           :x(rhs.x), y(rhs.y)
   {
   }
   ...
}

请注意,即使您提供了这个模板化的复制构造函数,编译器也会为您生成一个复制构造函数(当TU 相同时)。在这种情况下,您可以使用默认实现 - 它完全符合您的需要。但除此之外,您还必须显式定义非模板化构造函数(和复制赋值)。

【讨论】:

  • “请注意,一旦你提供了这个模板化的复制构造函数,你还必须明确地提供一个非模板化的构造函数”,这不是真的 :)
  • @Johannes:哦,好的,我明白了...我现在想怎么编辑... :)
  • 我更喜欢它,但我不确定您所说的“但除此之外”是什么意思。在什么情况下需要显式定义的非模板复制构造函数?我不明白。
  • @Johannes:当您对编译器生成的复制构造函数不满意时。我的观点是,提供一个模板化的“复制”构造函数不会阻止编译器生成一个真正的复制构造函数——当你从 EVector&lt;T&gt; 初始化 EVector&lt;T&gt; 时,将调用那个糟糕生成的构造函数——而不是模板的实例化与U = T