[英]Pointer to a class's private data member
Consider a class card
which has two public members, int suit
and int value
, and a template function that sorts an array of cards by the member I pass through a pointer-to-member, like this: 考虑一个具有两个公共成员的类
card
,该成员具有int suit
和int value
,以及一个模板函数,该函数按我通过指向成员的指针传递的成员对卡数组进行排序,如下所示:
//class card with public members
class card{
public:
int suit;
int value;
};
//sorting algorithm
template<typename m_pointer, typename iterator, typename Functype>
void sort_array(m_pointer member, iterator begin, iterator end, Functype pred){
iterator iter1=begin;
while(iter1!=end && ++iter1!=end){
iterator iter2=iter1;
while(iter2!=begin){
iterator iter3=iter2;
--iter3;
//here i use the pointer-to-member to sort the cards
if(pred((*iter3).*member, (*iter2).*member)){
std::swap(*iter3, *iter2);
}
else break;
--iter2;
}
}
}
int main(){
card array[3]={{3,1},{2,3},{4,5}};
//let's sort the cards by the suit value in a decreasing order
sort(&card::suit, array, array+3, [](int a, int b){return a<b;});
}
If the card member suit
is public there's obviously no problem, but what actually i didn't expected is that the same code doesn't give any trouble even if i declare suit
or value
as private members. 如果卡部件
suit
是公众有明显的没有问题,但究竟是什么,我没有预见的是,相同的代码不给任何麻烦,即使我宣布suit
或value
的私有成员。
class card{
int suit;
int value;
public://adding this for clarity, read forward
int* pointer_to_suit();
};
From what I know, I shouldn't be able to access private members from outside the class, and the only way to pass a pointer-to-member to a private member is through a member function which returns the member address, like this for example: 据我所知,我不应该从类外部访问私有成员,而将指向成员的指针传递给私有成员的唯一方法是通过返回成员地址的成员函数,例如例:
//function member of the class card
int* card::pointer_to_suit(){
return &suit;
}
So, why is it possible that the code above (the one with the template) works? 那么,为什么上面的代码(带有模板的代码)可以工作?
EDIT: Ok, the code above doesn't compile on it's own, but for some reason the following code compile fine to me. 编辑:好的,上面的代码不是自己编译的,但是出于某种原因,下面的代码对我来说很好。 I'll post the whole code since I've no idea where the trick for it to work might be, sorry for the mess:
我将发布整个代码,因为我不知道它可能起作用的诀窍在哪儿,对此一团糟:
template<typename m_pointer, typename iterator, typename Functype>
void sort_array(m_pointer member, iterator begin, iterator end, Functype pred){
iterator iter1=begin;
while(iter1!=end && ++iter1!=end){
iterator iter2=iter1;
while(iter2!=begin){
iterator iter3=iter2;
--iter3;
if(pred((*iter3).*puntatore, (*iter2).*puntatore)){
std::swap(*iter3, *iter2);
}
else break;
--iter2;
}
}
}
class card{
int suit;
int value;
public:
card(): suit(0), value(0) {}
card(int a, int b): suit(a), value(b){}
bool operator==(card a){return (suit==a.get_s() && value==a.get_v());}
bool operator!= (card a){return !(*this==a);}
void set_values(int a, int b){suit=a; value=b;}
int get_v(){return value;}
void set_v(int v){value=v;}
int get_s(){return suit;}
void set_s(int s){suit=s;}
double points_card();
};
template<typename iterator>
void ordina(iterator begin, iterator end, short (&suit)[4]){
for(int i=0; i<4; i++) suit[i]=0;
iterator it1=begin;
while(it1!=end){
if((*it1).get_s()==1) suit[0]+=1;
else if((*it1).get_s()==2) suit[1]+=1;
else if((*it1).get_s()==3) suit[2]+=1;
else if((*it1).get_s()==4) suit[3]+=1;
++it1;
}
sort_array(&carte::suit, begin, end, [](char a, char b){
if(b==0) return false;
else if(a==0) return true;
return (a>b);
});
sort_array(&carte::value, begin, begin+suit[0], [](int a, int b){return (a<b);});
sort_array(&carte::value, begin+suit[0], begin+suit[0]+suit[1], [](int a, int b){return (a<b);});
sort_array(&carte::value, begin+suit[0]+suit[1], begin+suit[0]+suit[1]+suit[2], [](int a, int b){return (a<b);});
sort_array(&carte::value, begin+suit[0]+suit[1]+suit[2], begin+suit[0]+suit[1]+suit[2]+suit[3],[](int a, int b){return (a<b);});
}
int main(){
card array[5]={{2,3},{1,2},{3,4},{4,5},{3,2}};
short suits[4]={1,1,2,1};
ordina(array, array+5, suits);
return 0;
}
EDIT 2: Yes, it runs http://coliru.stacked-crooked.com/a/d1795f0845770fcb . 编辑2:是的,它运行http://coliru.stacked-crooked.com/a/d1795f0845770fcb 。 Please note that the code here is not translated and there are some lines i didn't add for brevity.
请注意,此处的代码未翻译,为简洁起见,我没有添加一些行。
EDIT 3: As mentioned in Barry answer https://stackoverflow.com/a/35978073/5922196 , this is a gcc
compiler bug. 编辑3:如Barry回答https://stackoverflow.com/a/35978073/5922196所述 ,这是
gcc
编译器错误。 I used g++ 4.9.2
and this bug is still unresolved 我使用
g++ 4.9.2
,但此错误仍未解决
Congratulations, you found a bug in gcc! 恭喜,您在gcc中发现了一个错误! Here is a minimally reproduced example.
这是最小复制的示例。 Note that when we say minimal , we really do mean minimal .
请注意,当我们说最小时 ,我们实际上的意思是最小 。 I found this by just repeatedly deleting most of your lines of code.
我是通过重复删除大多数代码行来发现这一点的。 Also, always include things which compiler you used.
另外,请始终包括您使用的编译器。 Would've helped.
会有所帮助的。
gcc compiles this: gcc编译如下:
class X {
int mem;
};
template <class T>
auto foo(T) {
return &X::mem;
}
int main() {
auto p = foo(0);
}
clang does not. 铛没有。 clang is right.
铛是正确的。 This is gcc bug 41437 .
这是gcc错误41437 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.