| Trolltech Home | Qt-interest Home | Recent Threads | All Threads | Author | Date | |
| All threads index page 1 | |
Dear list,
I have defined a class and want to use it as a key type with a QMap. I
overloaded the < operator but the compiler can't find it. The class is
called TranslationDirection, it's defined in a namespace called LLCommon
and the compiler error is:
/usr/local/Trolltech/Qt-4.3.4/include/QtCore/qmap.h: In function ‘bool
qMapLessThanKey(const Key&, const Key&) [with Key =
LLCommon::TranslationDirection]’:
/usr/local/Trolltech/Qt-4.3.4/include/QtCore/qmap.h:667: instantiated
from ‘typename QMap<Key, T>::iterator QMap<Key, T>::erase(QMap<Key,
T>::iterator) [with Key = LLCommon::TranslationDirection, T = QAction*]’
/usr/local/Trolltech/Qt-4.3.4/include/QtCore/qmap.h:1015: instantiated
from ‘void QMutableMapIterator<Key, T>::remove() [with Key =
LLCommon::TranslationDirection, T = QAction*]’
LLCommon/TranslationDirectionManager.cpp:59: instantiated from here
/usr/local/Trolltech/Qt-4.3.4/include/QtCore/qmap.h:104: error: no match
for ‘operator<’ in ‘key1 < key2’
/usr/local/Trolltech/Qt-4.3.4/include/QtCore/qchar.h:361: note:
candidates are: bool operator<(QChar, QChar)
/usr/local/Trolltech/Qt-4.3.4/include/QtCore/qbytearray.h:470: note:
bool operator<(const QByteArray&, const QByteArray&)
/usr/local/Trolltech/Qt-4.3.4/include/QtCore/qbytearray.h:472: note:
bool operator<(const QByteArray&, const char*)
/usr/local/Trolltech/Qt-4.3.4/include/QtCore/qbytearray.h:474: note:
bool operator<(const char*, const QByteArray&)
/usr/local/Trolltech/Qt-4.3.4/include/QtCore/qstring.h:870: note:
bool operator<(const char*, const QString&)
/usr/local/Trolltech/Qt-4.3.4/include/QtCore/qstring.h:883: note:
bool operator<(const char*, const QLatin1String&)
/usr/local/Trolltech/Qt-4.3.4/include/QtCore/qstring.h:896: note:
bool operator<(const QLatin1String&, const QLatin1String&)
/usr/local/Trolltech/Qt-4.3.4/include/QtCore/qstring.h:1106: note:
bool operator<(const QStringRef&, const QStringRef&)
LLCommon/TranslationDirection.h:28: note: bool
operator<(LLCommon::TranslationDirection&, LLCommon::TranslationDirection&)
make[1]: Leaving directory `/home/daniel/eclipse-lexilector/Lexilector-Qt'
make[1]: *** [release/TranslationDirectionManager.o] Error 1
make: *** [release] Error 2
My understanding is that the compiler recognizes
LLCommon::TranslationDirection as the key type to use with QMap, that it
finds the definition of the overloaded operator but cannot match it.
Please, why is that?
Thanks
Daniel
---
PS:
The class' header file is:
#ifndef TRANSLATIONDIRECTION_H_
#define TRANSLATIONDIRECTION_H_
#include <QString>
namespace LLCommon
{
class TranslationDirection
{
public:
TranslationDirection(QString &, QString &);
~TranslationDirection();
bool operator==(TranslationDirection &) const;
QString & GetSourceLanguage();
QString & GetTargetLanguage();
QString & GetText();
private:
QString _source;
QString _target;
};
} // LLCommon
bool operator<(LLCommon::TranslationDirection & one,
LLCommon::TranslationDirection & other)
{
return one.GetText() < other.GetText();
}
#endif /*TRANSLATIONDIRECTION_H_*/
--
[ signature omitted ]
Daniel Storbeck wrote: > bool operator<(LLCommon::TranslationDirection & one, > LLCommon::TranslationDirection & other) I think you need to implement operator< as a member function of LLCommon::TranslationnDirection rather than a global function. Am I right? --Dave -- [ signature omitted ]
Dave Smith wrote:
> Daniel Storbeck wrote:
>> bool operator<(LLCommon::TranslationDirection & one,
>> LLCommon::TranslationDirection & other)
>
> I think you need to implement operator< as a member function of
> LLCommon::TranslationnDirection rather than a global function. Am I right?
>
> --Dave
Hi Dave,
that gives me the same compiler error:
/usr/local/Trolltech/Qt-4.3.4/include/QtCore/qmap.h:104: error: no match
for ‘operator<’ in ‘key1 < key2’
LLCommon/TranslationDirection.h:18: note: candidates are: bool
LLCommon::TranslationDirection::operator<(LLCommon::TranslationDirection&)
---
The header is:
#ifndef TRANSLATIONDIRECTION_H_
#define TRANSLATIONDIRECTION_H_
#include <QString>
namespace LLCommon
{
class TranslationDirection
{
public:
TranslationDirection(QString &, QString &);
~TranslationDirection();
// This one works.
bool operator==(TranslationDirection &) const;
bool operator<(TranslationDirection &);
QString & GetSourceLanguage();
QString & GetTargetLanguage();
QString & GetText();
private:
QString _source;
QString _target;
};
} // LLCommon
/*
// global function
bool operator<(LLCommon::TranslationDirection & one,
LLCommon::TranslationDirection & other)
{
return one.GetText() < other.GetText();
}
*/
#endif /*TRANSLATIONDIRECTION_H_*/
---
And the implementation:
#include "TranslationDirection.h"
namespace LLCommon
{
TranslationDirection::TranslationDirection(QString & source, QString &
target)
: _source(source), _target(target)
{
}
TranslationDirection::~TranslationDirection()
{
}
bool TranslationDirection::operator==(TranslationDirection & other) const
{
if ((_source == other.GetSourceLanguage())
&& (_target == other.GetTargetLanguage()))
return true;
else return false;
}
bool TranslationDirection::operator<(TranslationDirection & other)
{
return GetText() < other.GetText();
}
QString & TranslationDirection::GetSourceLanguage()
{
return _source;
}
QString & TranslationDirection::GetTargetLanguage()
{
return _target;
}
QString & TranslationDirection::GetText()
{
return QString((_source + " > " + _target));
}
}
---
I'll also try with two arguments.
Thank you
Daniel
--
[ signature omitted ]
You need to be const correct. For a member function use:
bool
TranslationDirection::operator<(TranslationDirection const & other) const
for a global function use:
bool operator<(TranslationDirection const & lhs,
TranslationDirection const & rhs)
GetText() should then also be const correct:
QString const & GetText() const;
Note that you can have both versions:
QString & GetText();
QString const & GetText() const;
But your current GetText returns a reference to a local variable. Your
compiler should warn against this. With gcc maybe you need -W -Wall.
QString & TranslationDirection::GetText()
{
return QString((_source + " > " + _target));
}
A more correct version would be:
QString TranslationDirection::GetText() const
{
return _source + " > " + _target;
}
--
[ signature omitted ]
Christoph Bartoschek wrote: > You need to be const correct. For a member function use: > > bool > TranslationDirection::operator<(TranslationDirection const & other) const > > for a global function use: > > bool operator<(TranslationDirection const & lhs, > TranslationDirection const & rhs) > It works! Thank you so much, Christoph. I actually used const in front of the type name and behind the signature but not behind the typename. Maybe I was mislead by the example code in the QMap Reference. Also the compiler error messages always listed candidates with the const keyword in front of the type names. Give me one last hint, please. How could I have figured out myself how to be const correct without trying all combinations? Thanks Daniel -- [ signature omitted ]
Daniel Storbeck wrote:
> It works! Thank you so much, Christoph. I actually used const in front
> of the type name and behind the signature but not behind the typename.
> Maybe I was mislead by the example code in the QMap Reference. Also the
> compiler error messages always listed candidates with the const keyword
> in front of the type names.
> Give me one last hint, please. How could I have figured out myself how
> to be const correct without trying all combinations?
> Thanks
> Daniel
1.
TranslationDirection const & lhs
is the same as
const TranslationDirection & lhs
The Trolltech documentation and lots of people prefer the second version. I
prefer the first one because it makes it easy to read the type from right
to left:
"lhs is a reference to a const TranslationDirection"
The correct signature could have also been:
bool operator<(const TranslationDirection & lhs,
const TranslationDirection & rhs);
2. How to find the error? The compiler does not give a very good message:
qmap.h:106: error: no match for âoperator<â in âkey1 < key2â
To find out the cause you need to look into qmap.h what type key1 and key2
have.
In qmap.h you see:
const Key &key1, const Key &key2
The compiler tells you what Key is (LLCommon::TranslationDirection). Then
you know that you need an operator< for two
const LLCommon::TranslationDirection &
3. One learns really quickly to be const correct wihtout reading the
compiler message. :)
Christoph
--
[ signature omitted ]
Christoph Bartoschek wrote: > TranslationDirection const & lhs > > is the same as > > const TranslationDirection & lhs I wasn't fully aware of that. Anyway, the reason why my code didn't work when I used the const keywords in front of the type name and behind the signature, was the GetText() function that wasn't declared also const. So, your hint on setting it const actually solved the problem. Thank you again. Best Daniel -- [ signature omitted ]
Daniel Storbeck wrote:
>Give me one last hint, please. How could I have figured out myself how
>to be const correct without trying all combinations?
What you needed was this:
bool operator<(Type t1, Type t2)
{
// ....
}
For efficiency purposes, you may want to pass by reference. After all,
you're just comparing two items, there's no need to create copies of
them.
Well, QMap doesn't allow you to modify the elements while it's sorting,
right? So you needed constant references:
bool operator<(const Type& t1, const Type& t2)
{
// ....
}
Now, if you have a constant object, you can only call const functions on
it. In general, all accessors are const. And I don't have to tell you
that, if the modifier applies to the _function_ (as opposed to the return
type or any arguments) it comes at the end:
QString GetText() const;
That's it!
Note that the following is syntactically the same:
const Type &
Type const &
the following is the same as well:
const Type *
Type const *
but the following is not the same as the last two:
Type * const
--
[ signature omitted ]
Attachment:
signature.asc
Description: This is a digitally signed message part.
Thiago Macieira wrote: > Now, if you have a constant object, you can only call const functions on > it. In general, all accessors are const. And I don't have to tell you > that, if the modifier applies to the _function_ (as opposed to the return > type or any arguments) it comes at the end: Yes, that pretty much explains the whole problem. And, yes, someone had to tell me, because I'm new to C++ and Qt, already came across that part of the "theory" but I forgot it and was completely lost. Thank you for reminding me. Best Daniel -- [ signature omitted ]
Hi Dave,
trying with two arguments results in the same error message plus:
...
LLCommon/TranslationDirection.h:23: error: ‘bool
LLCommon::TranslationDirection::operator<(LLCommon::TranslationDirection&,
LLCommon::TranslationDirection&)’ must take exactly one argument
/usr/local/Trolltech/Qt-4.3.4/include/QtCore/qmap.h: In function ‘bool
qMapLessThanKey(const Key&, const Key&) [with Key =
LLCommon::TranslationDirection]’:
/usr/local/Trolltech/Qt-4.3.4/include/QtCore/qmap.h:667: instantiated
from ‘typename QMap<Key, T>::iterator QMap<Key, T>::erase(QMap<Key,
T>::iterator) [with Key = LLCommon::TranslationDirection, T = QAction*]’
/usr/local/Trolltech/Qt-4.3.4/include/QtCore/qmap.h:1015: instantiated
from ‘void QMutableMapIterator<Key, T>::remove() [with Key =
LLCommon::TranslationDirection, T = QAction*]’
LLCommon/TranslationDirectionManager.cpp:59: instantiated from here
/usr/local/Trolltech/Qt-4.3.4/include/QtCore/qmap.h:104: error: no match
for ‘operator<’ in ‘key1 < key2’
LLCommon/TranslationDirection.h:23: note: candidates are: bool
LLCommon::TranslationDirection::operator<(LLCommon::TranslationDirection&,
LLCommon::TranslationDirection&)
/usr/local/Trolltech/Qt-4.3.4/include/QtCore/qchar.h:361: note:
bool operator<(QChar, QChar)
...
---
Header file:
...
bool operator<(TranslationDirection &, TranslationDirection &);
...
---
Implementation:
...
bool TranslationDirection::operator<(TranslationDirection & one,
TranslationDirection & other)
{
return one.GetText() < other.GetText();
}
...
---
I'm confused...
Thanks
Daniel
--
[ signature omitted ]