Рассмотрите класс 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;});
}
Если член карты suit
является публичной нет, очевидно, не проблема, но что на самом деле я не ожидал, что тот же код не дает каких-либо проблем, даже если я объявляю suit
или value
как частные члены.
class card{
int suit;
int value;
public://adding this for clarity, read forward
int* pointer_to_suit();
};
Из того, что я знаю, я не должен быть в состоянии получить доступ к частным членам вне класса, и единственным способом передать указатель на член к частному члену через функцию-член, которая возвращает адрес члена, как это, например:
//function member of the class card
int* card::pointer_to_suit(){
return &suit;
}
Итак, почему это возможно, что приведенный выше код (один с шаблоном) работает?
EDIT: Ok, приведенный выше код не компилируется по себе, но по какой-то причине следующий код компилироваться мне. Я выложу весь код, так как я понятия не имею, где трюк для того, чтобы работать может быть, извините за беспорядок:
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: Да, он работает http://coliru.stacked-crooked.com/a/d1795f0845770fcb. Обратите внимание, что код здесь не переведен, и есть несколько строк, которые я не добавлял для краткости.
EDIT 3: Как уже упоминалось в Барри ответить https://stackoverflow.com/a/35978073/5922196, это gcc
ошибка компилятора. Я использовал g++ 4.9.2
, и эта ошибка по-прежнему не решена.
Не могли бы вы включить класс карты? –
Почему вы заново изобретаете std :: sort()? –
Какой компилятор/версия вы используете, потому что он не компилировался в Visual Studio или GCC для меня, даже после того, как я исправил орфографию «class». http://ideone.com/vnwEkc – kfsone