2013-05-02 96 views
3

我正在實現C++表達式模板庫。我已經建立了一個適當的SubMatrixExpr類收集矩陣中的元素,使語法像在C++表達式模板中實現Matlab的冒號:運算符類

B = SubMatrix(A,1,3,2,10); 

這相當於Matlab的

B = A(1:3,2:10); 

當然,Matlab的語法比我更舒適。所以我的問題是

有沒有可能在C++中設置Matlab的冒號:運算符?

非常感謝您提前。

+0

不.C++中沒有冒號操作符。但是,您可能會讓其他運營商超負荷運行。 – David 2013-05-02 13:32:06

+3

您將無法獲得您在Matlab中使用的確切語法,但可以通過重載Matrix類的'operator()'來獲得更近的距離,以便它將兩個範圍作爲操作數。然後你可以寫出'B = A(範圍(1,3),範圍(2,10))',這*可能比'SubMatrix'版本更易讀。 – 2013-05-02 13:40:26

+0

@LucTouraille對'range()'部分有很好的提示,現在我把它寫入我的答案。謝謝。 – 2013-05-02 13:51:11

回答

3

簡答:沒有。 冒號不是有效的C++運算符,因此它不能被重載。如果可能的話,它仍然不可能實現你所需要的容易,因爲它肯定會優先於逗號運算符,這將使你的表達式成爲A((1:3),(2:10))的行,並且只允許你重載運算符如果其中一個操作數是用戶定義的類型(這裏不是這種情況)。

所以即使有其他操作員,您也無法做任何看起來像這樣的事情。

可以做:超載operator()你的矩陣類,爲明智的論點。這可能讓你寫類似B = A(1,3,2,10);,如果你定義一個operator()(int,int, int, int);

我首選的方案將是一個operator()採取以下兩種initializer_list小號C++ 11或兩個std::array<int,2>。前者必須檢查該列表是否包含兩個元素,後者需要一個笨拙的雙重大括號來初始化 - 這可能會在C++ 14或更高版本中消失(N3526,但afaik它不在C++ 14的CD中)。當然第三種可能性將是一個名爲類,你可以調用,呈現出範圍:

class Matrix { 
    /* ... */ 
public: 
    Matrix operator()(std::initializer_list<int> range1, std::initializer_list<int> range2); 
    //or: 
    Matrix operator()(std::array<int,2> range1, std::array<int,2> range2); 
    //or: 
    Matrix operator()(Range range1, Range range2); 

}; 

int main() { 
    Matrix A; 
    /* ... */ 
    Matrix B = A({1,3}, {2,10}); //beware of A({1,3,2,4,5}, {0}) ! 
    //or: 
    Matrix B = A({{1,3}}, {{2,10}}); //uhgs... 
    //or: 
    Matrix B = A(Range(1,3), Range(2,10)); //more verbose, but also more understandable 
} 
+0

謝謝。呂克Touraille的'範圍'的建議完美地爲我工作。 – JackOLantern 2013-05-03 08:01:21

0

另一個想法是使類型參數的構造函數char *,然後在構造函數中解析出的號碼:。例如,

A = B("3:4","8:end"); 

A = B(":","2"); 

這允許您做更多,如使用end關鍵字。