簡體   English   中英

用運算符子類化模板類

[英]Subclass a template class with operators

我正在嘗試為各種維度的數學向量創建類,並且由於它們的共同點,我創建了一個以向量大小作為模板參數的模板化基類。 我之所以子類化,是因為我想要不同的構造函數(例如Vec2f(float x, float y)Vec3f(float x, float y, float z) )和其他函數,例如3維矢量的叉積。

我的問題:基類中的operator+應該返回什么? 如果返回基類的實例,則Vec3f + Vec3f返回Vecnf ,但應返回Vec3f 可以通過某種方式實現嗎?

這是一個代碼示例:

template <size_t n>
class Vecnf {
public:
   Vecnf operator+(Vecnf const & vec) const {
      return Vecnf(*this) += vec;
   }
   Vecnf & operator+=(Vecnf const & vec) {
      for (int i = 0; i < n; ++i) {
         elements[i] += vec.elements[i];
      }
      return *this;
   }
protected:
   std::array<float, n> elements;
};

class Vec3f : public Vecnf<3> {
public:
   Vec3f(float x = 0.0f, float y = 0.0f, float z = 0.0f);
   Vec3f crossProd(Vec3f const & vec);
};

通過此實現,以下內容:

Vec3f a, b;
Vec3f c = a + b;

給出編譯時間錯誤

error: conversion from 'Vecnf<3u>' to non-scalar type 'Vec3f' requested

我在Windows 8 Pro上使用TDM GCC版本4.8.1。 我使用的是c ++ 11,因此您的解決方案也可以使用它,但是由於我認為這並不重要,因此我沒有用它來標記問題。 先感謝您 :)

您可以使構造函數成為可變參數模板,從而解決您的第一個問題,甚至不需要使用繼承:

template <size_t n>
class Vecnf
{
    std::array<float, n> elements;

public:
    template <typename ... Args>
    Vecnf(Args ... args): 
        elements {{static_cast<float>(args)...}}
    {}

    // other methods, operators etc...
};

現在,您可以根據需要將typedef為常用大小:

typedef Vecnf<3> Vec3f;

在我看來,您甚至可以通過為要存儲在數組中的類型添加另一個模板參數來改善這一點。 當然可以默認為float

同樣,以通用的方式實現跨產品應該不難...

您可以在vec3f上定義一個您想要執行的操作符+。 只要它是vecnf的子類型,它就可以具有與vecnf不同的返回類型,並且仍然會覆蓋它。

@JorenHeit引入了更好的解決方案; 實際上就是您想要的,以及兩個typedef。 該解決方案雖然與c ++ 03兼容,但不兼容。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM