2010-04-01 34 views
4

我想要一個結構爲token的結構,句子和段落信息具有開始/結束對。我也希望成員可以以兩種不同的方式訪問:作爲開始/結束對和單獨。鑑於:如何讓結構成員以不同方式訪問

struct token { 
    struct start_end { 
    int start; 
    int end; 
    }; 

    start_end pos; 
    start_end sent; 
    start_end para; 

    typedef start_end token::*start_end_ptr; 
}; 

我可以寫一個函數,說distance(),其計算上述三種start/end對象之間的距離:

int distance(token const &i, token const &j, token::start_end_ptr mbr) { 
    return (j.*mbr).start - (i.*mbr).end; 
} 

,並調用它像:

token i, j; 
    int d = distance(i, j, &token::pos); 

這將返回pos對的距離。但我也可以通過&token::sent&token::para,它做我想要的。因此,該功能是靈活的。

不過,現在我也想編寫一個函數,說max(),該計算的所有pos.start的最大值或全部pos.end或全部sent.start

如果我添加:

typedef int token::start_end::*int_ptr; 

我可以寫這樣的功能:

int max(list<token> const &l, token::int_ptr p) { 
    int m = numeric_limits<int>::min(); 
    for (list<token>::const_iterator i = l.begin(); i != l.end(); ++i) { 
    int n = (*i).pos.*p; // NOT WHAT I WANT: It hard-codes 'pos' 
    if (n > m) 
     m = n; 
    } 
    return m; 
} 

,並調用它像:

list<token> l; 
    l.push_back(i); 
    l.push_back(j); 
    int m = max(l, &token::start_end::start); 

但是,如上面的註釋中所示,我不想硬編碼pos。我希望可以靈活地訪問pos,sentpara中的任何一個的startend,它們將作爲參數傳遞給max()

我已經嘗試了幾件事情來讓這個工作(嘗試使用工會,匿名工會等),但我不能拿出一個數據結構,允許兩種方式的靈活性,而每個值只存儲一次。

任何想法如何組織token結構,所以我可以有我想要的?


在澄清嘗試

由於對整數的結構,我希望能夠以「片」數據以兩種不同的方式:

  1. 通過傳遞一個指針TO-成員的一個特定的開始/結束對,以便被調用的函數在任何一對上運行而不知道哪一對。來電者決定哪一對。
  2. 通過傳遞特定int的指針到構件(即,僅任何對一個int),使得被調用的函數的任何int操作而不需要知道其任一int或哪對所述int距離。來電者決定哪一對是哪個int

後者的另一個例子是將所有para.end或全部sent.start相加。

此外,重要的是:對於上述#2,我理想情況下只需傳遞一個指向成員的指針以減輕調用者的負擔。因此,我試圖用工會來解決問題。

#2,該結構將進行優化佈局,如:

struct token2 { 
    int pos_start; 
    int pos_end; 
    int sent_start; 
    int sent_end; 
    int para_start; 
    int para_end; 
}; 

關鍵是要有tokentoken2union莫名其妙覆蓋,但它並不明顯,如果/如何可以做,但滿足可訪問的要求。

+1

我不確定你在問什麼......你能澄清爲什麼你不能使用標準位置迭代器使用std :: string嗎?使用迭代器,您不需要使用寫入距離函數,可以使用內置的stl算法來計算迭代器之間的距離。 – 2010-04-01 18:19:44

+0

你能否試着重申一下你試圖用簡單的術語解決的問題?我認爲這裏有很多可以幫助你的人,但很難理解你正在努力做什麼。例如,什麼是「職位」?這是在一個文本字符串?起始/結束對是否索引爲一個字符串?謝謝,邁克。 – mikelong 2010-04-01 18:20:33

+0

我認爲他正在尋找一種方法來傳遞一個函數,它將成員拉出來。 – Stephen 2010-04-01 18:30:00

回答

2

只是一個嘗試。

int max(list<token> const &l,             
     token::int_ptr p,              
     token::start_end_ptr mbr) {           
    int m = numeric_limits<int>::min();           
    for (list<token>::const_iterator i = l.begin(); i != l.end(); ++i) {   
    int n = ((*i).*mbr).*p;    
    if (n > m)                 
     m = n;                  
    }                    
    return m;                  
}         
+0

嗯,是的,這是有效的,但根據我上面的說明,最初沒有提到的目標(對不起)是通過只傳遞一個指向成員的指針來實現的。 – 2010-04-01 19:02:55

+0

這編譯好g ++ 4.3。 – baol 2010-04-01 19:03:10

0

查看boost::bindboost::lambda庫。或者,如果您可以使用支持C++ 0x的編譯器,則可能需要使用某些較新的功能,而不是手動綁定成員屬性。然後你就可以使用它所提供的STL算法...

無論如何這都不可能做你想做的(我甚至沒有花時間去嘗試和編譯,所以還不如不編譯):

int max(list<token> const &l, token::start_end_ptr m, token::int_ptr p) { 
    int m = numeric_limits<int>::min(); 
    for (list<token>::const_iterator i = l.begin(); i != l.end(); ++i) { 
    int n = (*i).*m.*p; 
    if (n > m) 
     m = n; 
    } 
    return m; 
} 
int main() { 
    list<token> tks; 
    int x = max(tks, &token::pos, &token::start_end::start); 
} 

請注意,這不是路徑靈活性很好理解:你的算法結合的類型tokentoken::start_endint ......

的C++ 0x:

list <token> tks; 
int the_max = 0; 
for_each(tks.begin(), tks.end(), 
     [&the_max](token const & t) { the_max = max(the_max, t.pos.start); }); 
0
struct start_end { 
    int x; 
    int y; 
}; 
struct pairs { 
    struct start_end a; 
    struct start_end b; 
} 

那麼想法是切片數據在X或Y的動態操作?

int distance(start_end m, start_end n, int member_offset){ 
    int val_a = *(&m + member_offset); 
    int val_b = *(&n + member_offset); 
    int distance = val_b - val_a; 
    return distance; 
} 
+0

取消嵌套start_end結構不會改變任何內容。另外,在「struct start_end a;」中使用「struct」是不必要的:這是C++,而不是C. – 2010-04-01 19:01:53

+0

(1)您不顯示如何計算member_offset。 (2)在C和C++中,向指針添加偏移量是通過sizeof(T)來縮放指針的,在這種情況下T是start_end結構體。您首先必須將&m轉換爲指向char的指針,然後添加member_offset(大概會以字節爲單位)。 – 2010-04-01 19:14:22

1

我在回答baol建設了:

如果再加上一個token_reference結構和一些全局變量,我們可以有這樣的(益!):

struct token_reference 
{ 
    token::start_end_ptr start_end_ptr; 
    token::int_ptr int_ptr; 
}; 

token_reference pos_start = { &token::pos, &token::start_end::start }; 
token_reference pos_end = { &token::pos, &token::start_end::end }; 
token_reference sent_start = { &token::sent, &token::start_end::start }; 
token_reference sent_end = { &token::sent, &token::start_end::end }; 
token_reference para_start = { &token::para, &token::start_end::start }; 
token_reference para_end = { &token::para, &token::start_end::end }; 

int max(std::list<token> const &l, token_reference& ref) { 
    return max(l,ref.start_end_ptr,ref.int_ptr); 
} 

這樣調用:

tokenList aList; 
int value = max(aList,pos_start); 

你會得到一個函數list和另外一個參數。

+0

它們不必是真正的全局:它們可以是令牌的靜態數據成員。除此之外,解決方案並不壞。 – 2010-04-02 16:31:51

+0

但是:有沒有聰明的方法來做到這一點與工會(匿名或不)在令牌結構? – 2010-04-02 16:33:07