2016-08-17 37 views
0

我不是高級程序員。如何爲具有兩個(或更多)數組/矢量類型變量的類重載[]運算符?C++超載索引操作符爲多個數組/向量

class X 
{ 
protected: 
    std::vector<double> m_x, m_y; 
public: 
    double& operator[](const short &i) { return ???; } 
}; 

我應該用什麼爲???,或者我怎麼能做到這一點(也許添加其他的定義?),以能夠調用任何一個變量?
附加問題:這會允許其他類型的class derived : public X訪問m_xm_y用於書寫嗎?


UPDATE:

謝謝大家誰回答,但我害怕,如果我畫線,然後回答我的第一個問題是沒有,和第二肯定的。較長的版本意味着額外的structclass或簡單的setter/getters,我想通過使用一個簡單的函數來避免。
就目前而言,目前的解決方案是對每個變量的(臨時)引用,以避免多餘的X::鍵入(並且保持代碼清晰),因爲m_x會以某種方式存在。

+0

爲什麼你不使用'std :: vector >'而不是兩個單獨的向量? –

+2

一種方法,一個變量。試着給我們提供關於你的代碼的語義的更多信息。此外,額外的答案是*是*。 –

+0

@sorosh_sabz如果我有兩個以上的向量,我該怎麼辦? #Biagio它是一個接口類,它包含所有訪問變量的類的通用變量。他們的人數不確定,即會隨時間增長。 –

回答

0

你可以寫只是一個函數此,如:

double &get(unsigned int whichVector, unsigned int index) 
{ 
    return (whichVector == 0 ? m_x[index] : m_y[index]); 
} 

或使用操作符():

struct A 
    { 
     std::vector<int> a1; 
     std::vector<int> a2; 

     int operator()(int vec, int index) 
     { 
      return (vec == 0 ? a1[index] : a2[index]); 
     } 
    }; 
    A a; 
    auto var = a(0, 1); 

,但仍,這是有點兒奇怪:)也許你應該只給一個const參考外,如:

const std::vector<double> &getX() const { return m_x; } 

第二個問題:保護將轉換爲私有的公有繼承(chi LD /導出將有機會獲得這些承包商,客人)

0

您可以返回一個結構有兩個雙

struct A{ 
double& x; 
double& y; 
A(A& r) : x(r.x), y(r.y){} 
A(double& x, double& y) : x(x), y(y){} 
}; 


class X 
{ 
protected: 
    std::vector<double> m_x, m_y; 
public: 
    A operator[](const short &i) { 
     A result(m_x[i], m_y[i]); 
     return result; 
    } 
}; 

感謝編輯到@marcinj

+1

你可以使用std :: pair 代替寫入新類 –

+0

@sorosh_sabz他說兩個或多個變量。我可以用std :: pair做std :: pair 嗎? – burakozgul

+2

'std :: tuple'明顯。 – LogicStuff

0

如果使用混入不會讓你不舒服你可以使用tag分派,如:

#include <utility> 
#include <vector> 
#include <iostream> 

template <size_t I> 
struct IndexedVector { 
    std::vector<double> v; 
    IndexedVector():v(10){} 
}; 

template <size_t I> 
struct tag { 
    int i; 
}; 

template <size_t S, class = std::make_index_sequence<S>> 
struct MixinVector; 

template <size_t S, size_t... Is> 
struct MixinVector<S, std::index_sequence<Is...>>: IndexedVector<Is>... { 
    template <size_t I> 
    double &operator[](tag<I> i) { 
     return IndexedVector<I>::v[i.i]; 
    } 
}; 

int main() { 
    MixinVector<2> mv; 
    mv[tag<0>{0}] = 1.0; 
    std::cout << mv[tag<0>{0}] << std::endl; 
} 

要使用std::index_sequence但是你需要編譯器支持C++ 14(你可以儘管實現它自己在C++ 11)。通過簡單的MixinVector模板參數修改,該方法可輕鬆擴展到任意數量的向量。

+0

它看起來不錯,但它看起來像一個getter(x,i)的繪畫版本。迄今爲止所有的答案,儘管每個都提出了有效的觀點,但是讓代碼過於蓬鬆,這正是我首先想要避免的。這是一個可惜的重載,但我可能會訴諸使用'X :: m_x'等,也許指針或參考作爲捷徑。 –

0

假設你想m_xm_y索引對同一參數和一個返回值:

struct XGetter 
{ 
    double& x; 
    double& y; 
}; 

XGetter operator[](const short &i) { return { m_x[i], m_y[i] }; } 

而且const過載:

struct XGetterReadOnly 
{ 
    double x; 
    double y; 
}; 

XGetterReadOnly operator[](const short &i) const { return { m_x[i], m_y[i] }; } 

編譯器將優化掉的好工作中間類XGetterXGetterReadOnly在適當的情況下,如果你是一個新的C++,可能很難讓你的頭腦發熱。

0

無論是在概念上還是在設計層面上,都有很多破碎的東西。

你能夠將你的手指同時指向兩個不同的東西嗎?沒有?這就是爲什麼你不能使用一個索引來解決兩個不同的向量保留他們的區別。

你可以做很多事情:任何方式,以「結合」兩值INT一個好 通過視圖語法點:

return m_x[i]+m_y[x]return sin(m_x[i])*cos(m_y[i])return whatever_complicated_expression_you_like_much

但是,什麼那是什麼意思?重點是爲什麼你的班級裏有兩個向量?你想讓他們代表什麼?你是什​​麼意思(語義上)索引他們兩個?

什麼事情我可以做,以保持它們之間的區別是

auto operator[](int i) const 
{ return std::make_pair(m_x[i],m_y[i]); } 

,讓你得到一個std::pair<double,double>fistsecond件分別是m_x [i]和m_y [1]。

或者......你可以return std::vector<double>{m_x[i],m_y[i]};


關於您的其他問題:是的,繼承的公共使得新類能夠訪問受保護的部分:這是什麼保護的。

是的,你喜歡R/W:public,protected和private是關於可見性,而不是可讀性和可寫性。這就是常量。

但是,你的班級代表什麼?沒有這些信息,我們就無法確定什麼是有意義的,什麼不是。


好吧,說您的評論:

需要兩個不同的funcntions:一個用於讀取(double operator[](unsigned) const),一個用於寫入(double& operator[](unsigned) const

如果您知道載體具有已知長度-say 200-,你可以編碼一個像i/1000這樣的idex transforamtion來識別向量,並且i%1000獲得索引,這樣0..199地址第一個,1000..1199地址第二個2000..2199地址第三...等等

或...喲你可以使用std::pair<unsigned,unsigend>作爲索引(like operator[](const std::pair<unsigned,unsigned>& i),使用i.first來標識向量,並且使用i.second來索引它,然後調用x [{1,10}},x [{3,30}}等。

或者......你可以鏈縮放的矢量一起作爲

if(i<m_x.size()) return m_x[i]; i-=m_x:size(); 
if(i<m_y.size()) return m_y[i]; i-=m_y:size(); 
if(i<m_z.size()) return m_z[i]; i-=m_z:size(); 
... 

,讓您對其進行索引連續。

但可以使用的載體,而不是不同的矢量變量

的陣列,如果你有std::array<std::vector<double>,N> m;代替m_x,m_y和m_z上述代碼可以得到更多的算法溶液...

for(auto& v: m) 
{ 
    if(i<v.size()) return v[i]; 
    i-=v.size(); 
} 
+0

可以有兩個以上的向量,它們表示數據的累積,因此根據計算而變化。這些計算由外部派生類完成,每個類以其自己的方式完成,例如(不是真實的情況下)溼度,溫度等,並且派生類的數量可以變化(我可以增加風速或高度,例如, )。我想重載'[]'以便更快地讀取/寫入變量,而不是使用冗長的'Class :: getX(i)'和'Class:setX(var,i)'。 –

+0

@aconcernedcitizen查看更新 –