class DataTable
{
public:
class SortBase
{
public:
virtual bool operator()(const QString& a, const QString& b) = 0;
};
class SortByPath;
class SortByFreeSize;
typedef std::auto_ptr<SortBase> SorterPtr;
. . .
private:
SorterPtr m_lastSorted;
. . .
}
std::sort + предикаты-наследники
Есть такой класс
Код:
Есть два сортировщика:
Код:
class DirectoriesTable::SortByPath : public SortBase
{
Qt::SortOrder m_order;
public:
SortByPath(Qt::SortOrder order) : m_order(order) {}
bool operator()(const QString& a, const QString& b)
{
bool rc;
if (m_order==Qt::AscendingOrder)
rc = (a < b);
else
rc = (a > b);
return rc;
}
};
class DirectoriesTable::SortByFreeSize : public SortBase
{
Qt::SortOrder m_order;
public:
SortByFreeSize(Qt::SortOrder order) : m_order(order) {}
bool operator()(const QString& a, const QString& b)
{
bool rc;
if (m_order==Qt::AscendingOrder)
rc = getFreeSpaceValue(a) < getFreeSpaceValue(b);
else
rc = getFreeSpaceValue(a) > getFreeSpaceValue(b);
return rc;
}
};
{
Qt::SortOrder m_order;
public:
SortByPath(Qt::SortOrder order) : m_order(order) {}
bool operator()(const QString& a, const QString& b)
{
bool rc;
if (m_order==Qt::AscendingOrder)
rc = (a < b);
else
rc = (a > b);
return rc;
}
};
class DirectoriesTable::SortByFreeSize : public SortBase
{
Qt::SortOrder m_order;
public:
SortByFreeSize(Qt::SortOrder order) : m_order(order) {}
bool operator()(const QString& a, const QString& b)
{
bool rc;
if (m_order==Qt::AscendingOrder)
rc = getFreeSpaceValue(a) < getFreeSpaceValue(b);
else
rc = getFreeSpaceValue(a) > getFreeSpaceValue(b);
return rc;
}
};
И есть место, где я это пытаюсь заюзать. Так вот такой код проходит легко:
Код:
std::sort( m_directories.begin(), m_directories.end(), SortByFreeSize(Qt::AscendingOrder) );
А вот тут не катит:
Код:
SortBase* sorter = m_lastSorter.get();
if ( sorter )
{
SortBase& pr = *sorter;
std::sort( m_directories.begin(), m_directories.end(), pr );
}
if ( sorter )
{
SortBase& pr = *sorter;
std::sort( m_directories.begin(), m_directories.end(), pr );
}
Скажите, пожалуйста, что я упустил?
Код:
..\src\DirectoriesTable.cpp(174) : error C2893: Failed to specialize function template 'void std::sort(_RanIt,_RanIt,_Pr)'
With the following template arguments:
'QList<T>::iterator'
with
[
T=QString
]
'DirectoriesTable::SortBase'
..\src\DirectoriesTable.cpp(174) : error C2780: 'void std::sort(_RanIt,_RanIt)' : expects 2 arguments - 3 provided
D:\VS2008\VC\include\algorithm(3110) : see declaration of 'std::sort'
With the following template arguments:
'QList<T>::iterator'
with
[
T=QString
]
'DirectoriesTable::SortBase'
..\src\DirectoriesTable.cpp(174) : error C2780: 'void std::sort(_RanIt,_RanIt)' : expects 2 arguments - 3 provided
D:\VS2008\VC\include\algorithm(3110) : see declaration of 'std::sort'
а чем оно будет сравнивать в SortBase, если operator() чисто виртуальный
Посмотреть бы ещё чем m_lastSorted (умный указатель) инициализировался.
Цитата:
а чем оно будет сравнивать в SortBase, если operator() чисто виртуальный
А в чем проблема? чисто-не-чисто, но ведь он виртуальный, в зависимости от типа сортировщика должен быть вызван или SortByPath, или SortByFreeSize. Или я не прав в этом?
Цитата:
Посмотреть бы ещё чем m_lastSorted (умный указатель) инициализировался.
Умный указатель изначально инициализировался (если бы пример скомпилился) нулем, а затем, при первом включени сортировки - одним из new SortByPath или SortByName.
Но пример не компилится. А вот почему - я понять пока не в силах...
Цитата: KPI Student
в зависимости от типа сортировщика должен быть вызван или SortByPath, или SortByFreeSize. Или я не прав в этом?
он базовый, как он может знать о существовании наследников?
Цитата: oxotnik333
он базовый, как он может знать о существовании наследников?
Как-то так:
Код:
struct Base
{
virtual void Func() = 0;
};
struct Child: public Base
{
virtual void Func(){cout << "test" << endl;};
};
int main()
{
auto_ptr<Child> child(new Child);
Base& base = *child.get();
base.Func();
return 0;
}
{
virtual void Func() = 0;
};
struct Child: public Base
{
virtual void Func(){cout << "test" << endl;};
};
int main()
{
auto_ptr<Child> child(new Child);
Base& base = *child.get();
base.Func();
return 0;
}
Хотя меня такая инициализация ссылки немного пугает.
И, да, хочется посмотреть на код с умным указателем. Без него картинка не полная, я думаю.
интересно узнать, чем же все таки дело закончилось