C++ 指向类的指针';s私有数据成员

C++ 指向类的指针';s私有数据成员,c++,class,templates,pointers,pointer-to-member,C++,Class,Templates,Pointers,Pointer To Member,考虑一个类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 Fu

考虑一个类
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;});
}
据我所知,我不能从类外访问私有成员,将成员指针传递给私有成员的唯一方法是通过返回成员地址的成员函数,例如:

//function member of the class card
int* card::pointer_to_suit(){
   return &suit;
}
那么,为什么上面的代码(带有模板的代码)可以工作呢

编辑: 好的,上面的代码不是自己编译的,但是出于某种原因,下面的代码对我来说编译很好。我将发布整个代码,因为我不知道它的工作诀窍可能在哪里,很抱歉搞得一团糟:

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;
}
模板
void sort_数组(m_指针成员、迭代器开始、迭代器结束、Functype pred){
迭代器iter1=开始;
while(iter1!=end&&++iter1!=end){
迭代器iter2=iter1;
while(iter2!=开始){
迭代器iter3=iter2;
--iter3;
if(pred((*iter3)。*puntatore,(*iter2)。*puntatore)){
标准:交换(*iter3,*iter2);
}
否则就断了;
--iter2;
}
}
}
班级卡{
内服;
int值;
公众:
卡片():套装(0),值(0){}
卡片(内部a,内部b):套装(a),价值(b){}
bool操作符==(卡片a){return(suit==a.get_s()&&value==a.get_v());}
布尔运算符!=(卡a){return!(*this==a);}
无效集合_值(inta,intb){suit=a;value=b;}
int get_v(){返回值;}
无效集_v(int v){value=v;}
int get_s(){return suit;}
无效集_s(int s){suit=s;}
双积分卡();
};
模板
void ordina(迭代器开始、迭代器结束、短(&suit)[4]){
对于(int i=0;ib);
});

排序数组(&carte::value,begin,begin+suit[0],](inta,intb){return(a祝贺您,您在gcc中发现了一个bug!这里是一个最小复制的示例。请注意,当我们说最小时,我们实际上是指最小。我通过反复删除大部分代码行发现了这一点。此外,始终包含您使用的编译器。这会有所帮助

gcc汇编了以下内容:

class X {
    int mem;
};

template <class T>
auto foo(T) {
    return &X::mem;
}

int main() {
    auto p = foo(0);
}
X类{
int-mem;
};
模板
自动foo(T){
return&X::mem;
}
int main(){
自动p=foo(0);
}

clang没有。clang是对的。这是gcc错误。

你能包括card类吗?你为什么要重新发明std::sort()?你在使用什么编译器/版本,因为它没有在Visual Studio或gcc下为我编译,即使在我修复了“类”的拼写错误之后@SamVarshavchik只是因为我想使用我自己的函数,来试验模板、类等。在将两个类成员
私有化后,代码无法编译。无法复制。您需要发布一个演示您真正问题的帖子。
class X {
    int mem;
};

template <class T>
auto foo(T) {
    return &X::mem;
}

int main() {
    auto p = foo(0);
}