2016-12-24 8 views
0
#include <iostream> 
#include <algorithm> 
#include <numeric> 
#include <vector> 
using namespace std; 

class C 
{ 
public: 
    vector<int> CSort(); 
    bool Func(int x, int y); 
private: 
    vector<int> data; 
}; 

vector<int> C::CSort() 
{ 
    vector<int> result(data.size(), 0); 
    iota(result.begin(), result.end(), 0); 
    sort(result.begin(), result.end(), Func); 
    return result; 
} 

bool C::Func(int x, int y) 
{ 
    return (data[x] > data[y]); 
} 

В моем классе C, как определено выше, я хотел бы получить вектор заказа data с std::sort помощью функции члена Func. Результатом была ошибка:Каков правильный способ ссылки на функцию-член класса?

'C :: Func': нестандартный синтаксис; использование «&», чтобы создать указатель на член

Я считаю, что это что-то делать с Why doesn't reference-to-member exist in C++.

Однако, я не могу найти подходящий способ ссылки на эту функцию в std::sort. Как я могу реализовать его правильно?

+0

@ArchbishopOfBanterbury Вы были правы, и инициализирует вектор порядке убывания является хорошим напоминанием, спасибо большое;) –

+0

В стороне note, 'std :: sort (result, & C :: Func);' должен работать готово с предстоящими диапазонами TS. – Morwenn

ответ

0

Быстрый и грязный способ: Переместить Func вне класса.

#include <iostream> 
#include <algorithm> 
#include <numeric> 
#include <vector> 
using namespace std; 

class C 
{ 
public: 
    vector<int> CSort(); 
private: 
    vector<int> data; 
}; 

bool Func(int x, int y) { 
    return x > y; 
} 

vector<int> C::CSort() 
{ 
    vector<int> result(data.size(), 0); 
    // iota(data.begin(), data.end(), 0); 
    sort(data.begin(), data.end(), Func); 
    return result; 
} 
+0

Downvote почему? C++ ** не позволяет ссылаться на нестатические функции-члены. – gongzhitaao

+0

Он напрямую не отвечает на вопрос, но я не думаю, что он заслуживает понижения. (Особенно не без объяснения причин) – wally

+0

@gongzhitaao Я считаю, что допустил ошибку в своем коде. Извините за недопонимание. –

1

Лямбда будет работать:

#include <iostream> 
#include <algorithm> 
#include <numeric> 
#include <vector> 
using namespace std; 

class C 
{ 
public: 
    vector<int> CSort(); 
    bool Func(int x, int y); 
private: 
    vector<int> data; 
}; 

vector<int> C::CSort() 
{ 
    vector<int> result(data.size(), 0); 
    iota(data.begin(), data.end(), 0); 
    sort(data.begin(), data.end(), [this](auto& l, auto& r) {return Func(l, r); }); 
    return result; 
} 

bool C::Func(int x, int y) 
{ 
    return (data[x] > data[y]); 
} 

int main() 
{ 
    C c; 
} 

или связываются:

#include <iostream> 
#include <algorithm> 
#include <numeric> 
#include <vector> 
#include <functional> 

using namespace std; 

class C 
{ 
public: 
    vector<int> CSort(); 
    bool Func(int x, int y); 
private: 
    vector<int> data; 
}; 

vector<int> C::CSort() 
{ 
    vector<int> result(data.size(), 0); 
    iota(data.begin(), data.end(), 0); 
    sort(data.begin(), data.end(), std::bind(&C::Func,this,std::placeholders::_1,std::placeholders::_2)); 
    return result; 
} 

bool C::Func(int x, int y) 
{ 
    return (data[x] > data[y]); 
} 

int main() 
{ 
    C c; 
} 
+1

не используют 'std :: bind' для функций-членов до тех пор, пока вы не захватите функцию через [' std :: mem_fn'] (http://en.cppreference.com/w/cpp/utility/functional/ mem_fn), но, честно говоря, в C++ нет необходимости. – Mgetz

+0

@Mgetz Интересно. Но как это будет работать? Не нужно ли привязываться к конкретному экземпляру в этом примере? – wally

+1

Мы делаем, но на C++ безопасный способ захвата ссылки функцией-членом - использовать 'std :: mem_fn', это также простой способ. Возвращаемый объект функции гарантированно имеет параметр 'this' в качестве первого параметра. В то время как функция-указатель-член, как вы используете, не такая, как конкретная реализация реализации ABI. – Mgetz

1

У вас есть несколько вариантов:

Если у вас нет доступа к C++ 11 вы можете пойти в старую школу и реализовать свой собственный компаратор, который сохраняет состояние:

class C 
{ 
    friend struct MyComp; 
public: 
    vector<int> CSort(); 
private: 
    vector<int> data; 
}; 

struct MyComp 
{ 
    C* data; 
    MyComp(C* data) : data(data) {} 
    bool operator()(int x, int y) 
    { 
     return data->data[x] > data->data[y]; 
    } 
}; 

vector<int> C::CSort() 
{ 
    vector<int> result(data.size(), 0); 
    iota(data.begin(), data.end(), 0); 
    sort(data.begin(), data.end(), MyComp(this)); 
    return result; 
} 

Однако, если вы делаете, вы можете просто использовать лямбда:

vector<int> C::CSort() 
{ 
    vector<int> result(data.size(), 0); 
    iota(data.begin(), data.end(), 0); 
    sort(data.begin(), data.end(), [this] (int x, int y) { 
     return (data[x] > data[y]); 
    }); 
    return result; 
}