have a
std::list<MyBaseClass*> objects;
how ( mean a syntax) would you specialize std::greater
for the sort method of std::list
template<> class std::greater<MyBaseClass*> {
public:
bool operator()(const MyBaseClass*& lhs, const MyBaseClass*& rhs) const
{
return lhs->get_index() > rhs->get_index();
}
produces the error:
C2662: 'int MyBaseClass::get_index(void)' : cannot convert 'this' pointer from 'const MyBaseClass' to 'MyBaseClass &'
Conversion loses qualifiers
can you explain me the problem please?
Your implementation of eidos::MyBaseClass::get_index() needs to be marked as "const".
Related
Catch2 gives a Predicate class to make our own matcher. https://github.com/catchorg/Catch2/blob/master/docs/matchers.md
I simply test an unordered_map(decltype(getEntity2IdMap()) here.
namespace Generic {
Predicate<decltype(getEntity2IdMap())>(
[&](auto& maps) -> bool {
return maps.size() == 3 &&
maps["entity1"] == 0 &&
maps["entity2"] == 1 &&
maps["entity3"] == 2; },
"entities were inserted."));
The Predicate class has a simple definition.
template <typename T>
class PredicateMatcher : public MatcherBase<T> {
std::function<bool(T const&)> m_predicate;
std::string m_description;
public:
PredicateMatcher(std::function<bool(T const&)> const& elem, std::string const& descr)
:m_predicate(std::move(elem)),
m_description(Detail::finalizeDescription(descr))
{}
bool match( T const& item ) const override {
return m_predicate(item);
}
std::string describe() const override {
return m_description;
}
};
} // namespace Generic
// The following functions create the actual matcher objects.
// The user has to explicitly specify type to the function, because
// infering std::function<bool(T const&)> is hard (but possible) and
// requires a lot of TMP.
template<typename T>
Generic::PredicateMatcher<T> Predicate(std::function<bool(T const&)> const& predicate, std::string const& description = "") {
return Generic::PredicateMatcher<T>(predicate, description);
}
However, clang++ yields a type mismatch.
error: no viable overloaded operator[] for type 'const std::__1::unordered_map<std::__1::basic_string<char>,
unsigned int, std::__1::hash<std::__1::basic_string<char> >, std::__1::equal_to<std::__1::basic_string<char> >,
std::__1::allocator<std::__1::pair<const std::__1::basic_string<char>, unsigned int> > >'
I am wondering the maps type here or I misunderstood the lambda context for "/m/entity1".
The full error message is likely to be something like:
<source>:7:21: error: no viable overloaded operator[] for type 'const std::unordered_map<std::string, int>' (aka 'const unordered_map<basic_string<char>, int>')
std::cout << map["test" ] == 1;
~~~^~~~~~~
unordered_map.h:963:7: note: candidate function not viable: 'this' argument has type 'const std::unordered_map<std::string, int>' (aka 'const unordered_map<basic_string<char>, int>'), but method is not marked const
operator[](const key_type& __k)
^
unordered_map.h:967:7: note: candidate function not viable: 'this' argument has type 'const std::unordered_map<std::string, int>' (aka 'const unordered_map<basic_string<char>, int>'), but method is not marked const
operator[](key_type&& __k)
The key clue is 'this' argument has type 'const.... but method is not marked const.
Your maps are const but operator[] is not const, you need to use find() or at() to retrieve values from a const std::map or std::unordered_map.
I need to compare if two list equal, so I write down following codes in my VS2005 project
#include <list>
class sitesInfo
{
public:
bool operator==(const sitesInfo &rh)
{
return this->a == rh.a;
}
private:
int a;
};
int _tmain(int argc, _TCHAR* argv[])
{
std::list<sitesInfo> list1;
std::list<sitesInfo> list2;
bool ret = (list1 == list2);
return 0;
}
here sitesInfo is EqualityComparable, which is what is required in the c++ standard:
Table 96 — Container requirements
Why do I get following compile error which prevent me from comparing two list?
vs2005\vc\include\xutility(2476) : error C2678: binary '==' : no operator found which takes a left-hand operand of type 'const sitesInfo' (or there is no acceptable conversion)
d:\my documents\visual studio 2005\projects\test\test\test.cpp(10): could be 'bool sitesInfo::operator ==(const sitesInfo &)'
while trying to match the argument list '(const sitesInfo, const sitesInfo)'
1> e:\program files\vs2005\vc\include\xutility(2602) : see reference to function template instantiation 'std::pair<_Ty1,_Ty2> std::_Mismatch<_InIt1,_InIt2,std::forward_iterator_tag>(_InIt1,_InIt1,_InIt2,_InItCats,std::_Range_checked_iterator_tag)' being compiled
with
[
_Ty1=std::list<sitesInfo>::_Const_iterator<false>,
_Ty2=std::list<sitesInfo>::_Const_iterator<true>,
_InIt1=std::list<sitesInfo>::_Const_iterator<false>,
_InIt2=std::list<sitesInfo>::_Const_iterator<true>,
_InItCats=std::forward_iterator_tag
]
e:\program files\vs2005\vc\include\xutility(2674) : see reference to function template instantiation 'bool std::_Equal<std::list<_Ty>::_Const_iterator<_Secure_validation>,_InIt2,std::_Iter_random_helper<_Cat1,_Cat2>::_Iter_random_cat>(_InIt1,_InIt1,_InIt2,_InItCats,std::_Range_checked_iterator_tag)' being compiled
with
_Ty=sitesInfo,
_Secure_validation=false,
_InIt2=std::list<sitesInfo>::_Const_iterator<true>,
_Cat1=std::list<sitesInfo>::_Const_iterator<true>::iterator_category,
_Cat2=std::list<sitesInfo>::_Const_iterator<true>::iterator_category,
_InIt1=std::list<sitesInfo>::_Const_iterator<false>,
_InItCats=std::_Iter_random_helper<std::list<sitesInfo>::_Const_iterator<true>::iterator_category,std::list<sitesInfo>::_Const_iterator<true>::iterator_category>::_Iter_random_cat
]
e:\program files\vs2005\vc\include\list(1261) : see reference to function template instantiation 'bool std::equal<std::list<_Ty>::_Const_iterator<_Secure_validation>,std::list<_Ty>::_Const_iterator<_Secure_validation>>(_InIt1,_InIt1,_InIt2)' being compiled
with
[
_Ty=sitesInfo,
_Secure_validation=true,
_InIt1=std::list<sitesInfo>::_Const_iterator<true>,
_InIt2=std::list<sitesInfo>::_Const_iterator<true>
]
d:\my documents\visual studio 2005\projects\test\test\test.cpp(23) : see reference to function template instantiation 'bool std::operator ==<sitesInfo,std::allocator<_Ty>>(const std::list<_Ty> &,const std::list<_Ty> &)' being compiled
with
[
_Ty=sitesInfo
]
I can only get it to compile by defining a global operator== whose parameter type is const sitesInfo&
bool operator==(const sitesInfo &rh, const sitesInfo &rs)
The issue with your member operator== is it is not marked const. When std::list checks for equality it does so against two const elements. That means that your operator== is ignored as it is not marked as const so it cannot be called on a const object.
To fix this we simply mark the function as const like
bool operator==(const sitesInfo &rh) const
{
return this->a == rh.a;
}
And now it will compile and run
The free function works as free functions do not have a const qualification and it takes two const objects. If you had
bool operator==(sitesInfo &rh, sitesInfo &rs)
Then that would fail to compile as you are trying to remove the constness of the objects.
Read the error carefully. Your operator :
bool operator==(const sitesInfo &rh)
{
return this->a == rh.a;
}
is ok for non-const objects and any right hand side, but for const objects you have to provide an operator like this:
bool operator==(const sitesInfo &rh) const
{
return this->a == rh.a;
}
The reason why the operator has to be const is that lists operator == has works on const lists:
bool operator==( const list& lhs, const list& rhs ); // template parameters
// omitted for the sake of clarity
thus it can only call the const version of its elements comparison operator.
I am facing an error while trying to add a reference of object to vector of pointers:
template <class Tpoint, class Tmodel> Tmodel ransac<Tpoint, Tmodel>::perform_fitting(const std::vector<Tpoint>& data){
std::vector<Tpoint*> also_inliers;
for (const auto& pnt : data){
if (fit_point(pnt, may_be_model) <= t){
also_inliers.push_back(&pnt); //error here
}
} // ! for range
}
Error message from VS.NET 2013:
Error 88 error C2664: 'void std::vector>::push_back(cv::Point_ *const &)' : cannot convert argument 1 from 'const cv::Point_ *' to
'cv::Point_ *&&'
You capture pnt as const auto&, but you then try to push it into a vector containing non-const pointers. This violates const-correctness.
Either change also_inliers to std::vector<const Tpoint*> if you aren't going to be modifying those pointee objects or capture by auto& if you need the modification.
I have a templated class:
template<class T>
class MyClass
{
public:
MyClass(T mem)
{
member = mem;
}
T& GetMember() const
{
return(member);
}
T member;
};
and then I do this:
MyClass<bool> test(true);
bool someBool = test.GetMember();
And I get a compile error saying it can't convert 'bool' to 'bool&'
How can I fix this?
The problem is you have a const member function, but you are returning a mutable reference from it. (btw cl's error message is error C2440: 'return' : cannot convert from 'const bool' to 'bool &' which makes that clear). That is probably is not your real intent, so either use
T GetMember() const
{
return member;
}
or
const T& GetMember() const
{
return member;
}
T& GetMember() const
should be
const T& GetMember() const
const is not just a keyword to make your code look safer, it acutally enforces your code to be safer ;)
I'm tracking down a C++ compiler error which I can't figure out. I've reduced it to this code:
#include <boost/config.hpp>
#include <boost/type_traits/remove_reference.hpp>
template<typename T> inline const T bar( T in )
{
typedef BOOST_DEDUCED_TYPENAME boost::remove_reference<T>::type nonref;
const nonref* inPtr = ∈
return *inPtr;
}
class Foo
{
};
int main()
{
Foo foo;
const Foo& ref = bar< Foo& >( foo );
}
which results in:
tt.cpp: In function ‘const T bar(T) [with T = Foo&]’:
tt.cpp:19:39: instantiated from here
tt.cpp:9:13: error: invalid initialization of reference of type ‘Foo&’ from expression of type ‘const nonref {aka const Foo}’
What's the actual issue here? Why is the const missing in the return value? I need the remove_reference since the actual code requires it.
Applying const to a reference type does nothing. You need to make the template argument const foo &, or else remove the reference and then add back both const and the reference in the function signature itself.
See also When should I use remove_reference and add_reference? particularly the second paragraph.
Using VisualStudio 2008 I get the following error
error C2440: 'return' : cannot convert from 'const nonref' to 'Foo &'
Changing bat to
template<typename T> inline const typename boost::remove_reference<T>::type& bar( T in )
{
typedef BOOST_DEDUCED_TYPENAME boost::remove_reference<T>::type nonref;
const nonref* inPtr = ∈
return *inPtr;
}
fixes this and the code compiles.
Returning const T from your function doesn't do what you are expecting. From your code I understand that you expect it to return const Foo&, which is a reference to an immutable object of type Foo.
But when T is Foo&, the expression const T means an immutable reference to an object of type Foo. Since the references are always immutable, the const part is just dropped (according to the paragraph 8.3.2 of the spec)! That is, your function returns Foo& and not const Foo& and that's what the compiler tries to tell you.