цитата из
n3376.pdf стр. 715:
X(i,j,c) X a(i,j,c);
Effects: Constructs an empty container and inserts elements from the range [i, j) into it; uses c as a comparison object.
Пытаюсь заставить работать именно этот конструктор:
std::set<int> m3(m1.cbegin(), m1.cend(), std::greater<int>);
получаю
ошибка: expected primary-expression before «)» token
Что не так делаю? Можно ли критерий засунуть в фактические параметры конструктора или что обзозначает приведенная запись в стандарте?
P.S. другие конструкторы нормально отработали:
std::set<int> m3(m1.cbegin(), m1.cend());
std::set<int> m3(m1);
std::set<int> m3(std::greater<int>);
...
Передача критериев сортировки в параметры шаблона и конктруктора успешна тоже.
Здравствуйте, b.armaley, Вы писали:
BA>BA>std::set<int> m3(m1.cbegin(), m1.cend(), std::greater<int>);
BA>
BA>Что не так делаю?
std::set<int, std::greater<int> > m3(m1.cbegin(), m1.cend());
Здравствуйте, b.armaley, Вы писали:
std::greater<int> — это тип, а тебе надо объект, т.е.
std::greater<int>(), поэтому
BA>BA>std::set<int, std::greater<int>> m3(m1.cbegin(), m1.cend(), std::greater<int>());
BA>P.S. другие конструкторы нормально отработали:
BA>BA>std::set<int> m3(std::greater<int>);
BA>
Это — объявление функции.
Здравствуйте, jazzer, Вы писали:
J>Здравствуйте, b.armaley, Вы писали:
J>std::greater<int> — это тип, а тебе надо объект, т.е. std::greater<int>(), поэтому
BA>>BA>>std::set<int, std::greater<int>> m3(m1.cbegin(), m1.cend(), std::greater<int>());
J>
я пробовал
std::set<int> m3(m1.cbegin(), m1.cend(), std::greater<int>() );
$ c++ -std=c++11 test.cpp && ./a.out
ошибка: нет подходящей функции для вызова «std::set<int>::set(std::set<int>::iterator, std::set<int>::iterator, std::greater<int>)»
замечание: candidates are:
In file included from /usr/include/c++/4.7/set:61:0,
from less4_5-1.cpp:2:
/usr/include/c++/4.7/bits/stl_set.h:219:7: замечание: std::set<_Key, _Compare, _Alloc>::set(std::initializer_list<_CharT>, const _Compare&, const allocator_type&) [with _Key = int; _Compare = std::less<int>; _Alloc = std::allocator<int>; std::set<_Key, _Compare, _Alloc>::allocator_type = std::allocator<int>]
...
BA>>P.S. другие конструкторы нормально отработали:
BA>>BA>>std::set<int> m3(std::greater<int>);
BA>>
J>Это — объявление функции.
согласен, просто промахнулся при наборе поста
Здравствуйте, b.armaley, Вы писали:
BA>я пробовал
не то пробовали, будьте внимательны
скопируйте код:
std::set<int, std::greater<int>> m3(m1.cbegin(), m1.cend(), std::greater<int>());
Здравствуйте, b.armaley, Вы писали:
BA>Пытаюсь заставить работать именно этот конструктор:
BA>BA>std::set<int> m3(m1.cbegin(), m1.cend(), std::greater<int>);
BA>
BA>получаю
BA>BA>ошибка: expected primary-expression before «)» token
BA>
BA>Что не так делаю? Можно ли критерий засунуть в фактические параметры конструктора или что обзозначает приведенная запись в стандарте?
Не так здесь сразу несколько вещей.
1. Тип компаратора является параметром шаблона
класса. По умолчанию там std::less<Key>.
Подсовывая в конструктор компаратор любого другого типа, — естественно, получаешь ошибку.
2. Хочешь передать объект компаратора — так изволь его сконструировать: std::greater<int>
(). Без () это просто имя типа.
По аналогии:
void foo(int x, int y);
int main() { foo(123, int); } // ну очевидно же, что неправильно?
3. Если тебе нужно, чтобы несколько
однотипных объектов-множеств выполняли сравнение по-разному, то у них должны быть полиморфные компараторы, — параметризуемые в рантайме. Примерно так
std::vector<int> v;
typedef std::set<int, MyCoolComparator> MyCoolSet;
MyCoolSet sx( v.begin(), v.end(), MyCoolComparator(please_order_ascending) );
MyCoolSet sy( v.begin(), v.end(), MyCoolComparator(please_order_descending) );
Как именно устроены такие полиморфные компараторы — тут есть несколько вариантов. На выбор
//////////////////
// параметр-флажок
class Comp1
{
bool ascending;
public:
Comp1(bool a) : ascending(a) {}
bool operator() (int x, int y) const { return a ? x<y : x>y; }
};
... set<int,Comp1> s1( Comp1(true) ); ...
/////////////////////////////
// полиморфизм на интерфейсах
struct IComp2
{
virtual ~IComp2() {}
virtual bool operator() (int x, int y) const = 0;
};
class Comp2Facade
{
shared_ptr<IComp> impl;
public:
Comp2(IComp* i) : impl(i) { assert(i); }
bool operator() (int x, int y) const { return (*i)(x,y); }
};
class Comp2A : public IComp2
{
bool operator() (int x, int y) const { return x<y; }
};
class Comp2D : public IComp2
{
bool operator() (int x, int y) const { return x>y; }
};
... set<int, Comp2Facade> s2( Comp2Facade(new Comp2A) ); ...
////////////////////////////////////
// полиморфизм на функциях и лямбдах
typedef function<bool(int,int)> Comp3;
...
bool ascending(int x, int y) { return x<y; }
...
set<int, Comp3> s3a( [](int x, int y) -> bool { return x<y; } ),
s3b( less<int>() ),
s3c( ascending );
...