我希望结构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
。我希望start
,end
或pos
sent
,para
或max()
可以灵活地访问token
,int
或int
作为参数传递给{{1} }}
我已经尝试了几种方法来实现这一点(尝试使用工会,匿名工会等)但我无法想出一种数据结构,它允许两种方式的灵活性,同时每个值只存储一次。
任何想法如何组织int
结构,以便我可以得到我想要的东西?
给定整数对的结构,我希望能够以两种不同的方式“切片”数据:
int
的成员指针(即,只有一个 int
的任何一对),以便被调用的函数对任何{{}进行操作1}}不知道哪个int
或哪个对para.end
来自哪个。来电者决定哪一对sent.start
。后者的另一个例子是总结所有struct token2 {
int pos_start;
int pos_end;
int sent_start;
int sent_end;
int para_start;
int para_end;
};
或所有token
。
此外,重要的是:对于上面的#2,我理想情况下只想传递一个指向成员的指针来减轻调用者的负担。因此,我试图用工会来解决问题。
对于#2,结构将最佳布局如下:
token2
诀窍是让union
和{{1}}以某种方式覆盖{{1}},但是不明白是否/如何做到这一点并满足可访问的要求。
答案 0 :(得分: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;
}
答案 1 :(得分:1)
我正在建立baol给出的答案:
如果我们添加一个token_reference
结构和一些全局(ick!)变量,我们可以这样:
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
和另外一个参数的函数。
答案 2 :(得分:0)
查看boost::bind
或boost::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 );
}
请注意,这不是灵活理解的途径:您将算法绑定到类型token
,token::start_end
和int
......
的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 ); } );
答案 3 :(得分: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;
}