Cannot convert 'const T*' to 'T*&&' - c++

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.

Related

how would you specialize std::greater

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".

How to use lambda to erase empty vector cells?

I have a vector:
std::vector<Edge> edges(num);
which contain empty cells at the end, which I would like to remove using lambda but when I did:
edges.erase(std::remove_if(edges.begin(), edges.end(),
std::mem_fn(&std::Edge::empty), edges.end() );
I got this error:
error C2664: 'bool main::<lambda_6f33349b59d49f69703a5fa6a8c5995a>::operator ()(const std::vector<_Ty> &) const' : cannot convert parameter 1 from 'Edge' to 'const std::vector<_Ty> &'
What do I do now?
How to use lambda to erase empty vector cells?
You just need to provide a simple lambda that returns true if an Edge is empty:
edges.erase(std::remove_if(edges.begin(),
edges.end(),
[](const Edge& e){return e.empty();}),
edges.end() );
This assumes Edge has a suitable member function empty():
class Edge
{
public:
bool empty() const { .... }
// as before
};

Error in parameter conversion using templates

I have a function template that takes a vector and an element of a given type and returns the position of the element in the vector. This is the code for this function template:
template<class T>
int findElement(const vector<T> &vec, const T &ele)
{
for(size_t i = 0; i < vec.size(); i++)
{
if(ele == vec[i])
return i;
}
return -1;
}
And here's the function call:
findElement<double>(intVec, ele);
But I get this error when I call the function:
error C2664: 'findElement' : cannot convert parameter 1 from 'std::vector<_Ty>' to 'const std::vector<_Ty,_Ax> &'
And this error is same even if I remove the const for the vector in the function template definition:
error C2664: 'findElement' : cannot convert parameter 1 from 'std::vector<_Ty>' to 'std::vector<_Ty,_Ax> &'
However, when I make the function call as
findElement(intVec, ele)
I do not get any error.
What is the reason for this behavior?
Seems like compiler cannot convert vector<double> to vector<int>. Since by logic way, intVec is vector of ints, isn't it? And you say compiler, that you want vector of doubles.
You cannot convert vector<T> to vector<U>, since vector has no following conversion constructor, and it's nice.

Visual Studio 2008 Bug in <algorithm>? includes algo seems to inadvertently swap the order of iterators on line 3795

I'm trying to get the includes algorithm to work on a set and map by comparing the map's keys to the set's values. The issue that needs to be circumvented is of course that map<K,V>::value_type is pair<K,V> while set<V>::value_type is V so these are not going to work with the default includes predicate<T> which expects the same value type for both arguments.
I am hence writing the below predicate classes to get around this
template <class P,class K>
struct mapKey_set_less : public std::binary_function<P,K,bool>
{
inline bool operator() (const P& x, const K& y) const {return x.first < y ;};
};
template <class K,class P>
struct set_mapKey_less : public std::binary_function<K,P,bool>
{
inline bool operator() (const K& x, const P& y) const {return x < y.first ;};
};
However the template instantiator is throwing up on line 313 of the VS2008 xutility file
if (!_Pred(_Left, _Right))
with the message that it cannot convert parameter 1 from const V to const std::pair<_Ty1,_Ty2>
This seems to be caused by line 3795 of the file
if (_DEBUG_LT_PRED(_Pred, *_First2, *_First1))
where the first and second arguments seem to have been swapped
Compiling in Release Configuration gives the same error on line 3795, so it seems the Visual Studio implementation wants you to go through this code unless you tinker with whatever switch (if any) removes this '_DEBUG_LT_PRED' macro.
My question is:
Is this a bug in Visual Studio or is there a reason for this to be this way and I am making a mistake? I haven't done any C++ in over a decade and had to pick up last week to get some speed ups in some tight loops so need all the help I can get.
Thanks all
Nice,
I didn't think about the requirements of the algo. Makes sense it needs to check "less than" from both sides.
Not getting much joy getting this to compile though.
With my previous code of
template <class P,class K>
struct mapKey_set_cmp //: public std::binary_function<P,K,bool>
{
inline bool operator() (const P& x, const K& y) const {return x.first < y ;};
};
I was getting
error C2664: 'bool mapKey_set_cmp<P,K>::operator ()(const P &,const K &) const' :
cannot convert parameter 1 from 'const double' to 'const std::pair<_Ty1,_Ty2> &'
which makes sense as there is no operator() that can take a double as its 1st argument.
With the additional overloaded operator()
template <class P,class K>
struct mapKey_set_cmp //: public std::binary_function<P,K,bool>
{
inline bool operator() (const P& x, const K& y) const {return x.first < y ;};
inline bool operator() (const K& x, const P& y) const {return x < y.first ;};
};
I am now getting
error C2664: 'bool mapKey_set_cmp<P,K>::operator ()(const K &,const P &) const' :
cannot convert parameter 1 from 'const std::pair<_Ty1,_Ty2>' to 'const double &'
error C2664: 'bool mapKey_set_cmp<P,K>::operator ()(const K &,const P &) const' :
cannot convert parameter 1 from 'const std::pair<_Ty1,_Ty2>' to 'const double &'
error C2664: 'bool mapKey_set_cmp<P,K>::operator ()(const K &,const P &) const' :
cannot convert parameter 2 from 'const double' to 'const std::pair<_Ty1,_Ty2> &'
error C2664: 'bool mapKey_set_cmp<P,K>::operator ()(const K &,const P &) const' :
cannot convert parameter 2 from 'const double' to 'const std::pair<_Ty1,_Ty2> &'
Of note is that all the errors seem to reffer to the 2nd operator(), the one with the K 1st and P 2nd. And yes, none of the conversions mentioned should be possible on that operator. But why isn't the compiler trying the other operator? ie the one on which those conversions should be allowed. (BTW the errors are repeated because they each occur on two different lines in case you are wondering)
Another thing this could be is of course const incorrectness. It's been a while so I'll try to think that through.
Thanks for the help
Edit on 15 May 2013
I had to "get on with it" so circumvented this problem by puting my map Keys into a set so that I could call the includes algo on two sets (incurring the obvious performance penalty). I would still like to solve this properly though. Here is all the code neded to replicate the compiler error I am describing with Visual Studio 2008
template <class PAIR,class KEY>
struct mapKey_set_less : public std::binary_function<PAIR,KEY,bool>
{
inline bool operator() (const PAIR& x, const KEY& y) const {return x.first < y ;};
inline bool operator() (const KEY& x, const PAIR& y) const {return x < y.first ;};
};
int _tmain(int argc, _TCHAR* argv[])
{
map<string,double> theMap;
theMap["arse"] = 1;
set<string> theSet;
theSet.insert("arse");
typedef map<string,double>::iterator MI;
MI mi(theMap.begin()), miend(theMap.end());
typedef set<string>::iterator SI;
SI si(theSet.begin()), siend(theSet.end());
typedef mapKey_set_less< pair<string,double>,string> cmp;
if (includes(mi,miend,si,siend,cmp()))
{}
}
The compiler spits out
Error 1 error C2664: 'bool mapKey_set_less<PAIR,KEY>::operator ()(const KEY &,const PAIR &) const' : cannot convert parameter 1 from 'std::pair<_Ty1,_Ty2>' to 'const std::string &' c:\program files (x86)\microsoft visual studio 9.0\vc\include\xutility 346
Error 2 error C2664: 'bool mapKey_set_less<PAIR,KEY>::operator ()(const KEY &,const PAIR &) const' : cannot convert parameter 1 from 'std::pair<_Ty1,_Ty2>' to 'const std::string &' c:\program files (x86)\microsoft visual studio 9.0\vc\include\xutility 348
Error 3 error C2664: 'bool mapKey_set_less<PAIR,KEY>::operator ()(const KEY &,const PAIR &) const' : cannot convert parameter 2 from 'std::basic_string<_Elem,_Traits,_Ax>' to 'const std::pair<_Ty1,_Ty2> &' c:\program files (x86)\microsoft visual studio 9.0\vc\include\xutility 346
Error 4 error C2664: 'bool mapKey_set_less<PAIR,KEY>::operator ()(const KEY &,const PAIR &) const' : cannot convert parameter 2 from 'std::basic_string<_Elem,_Traits,_Ax>' to 'const std::pair<_Ty1,_Ty2> &' c:\program files (x86)\microsoft visual studio 9.0\vc\include\xutility 348
Looking at the 1st error alone it seems that it wants to use the operator()(KEY,PAIR) to pass in PAIR,KEY. Why is it ignoring the available operator()(PAIR,KEY)???
The other errors are all in the same vein, the compiler "appears" to ignore a perfectly good overloaded operator
Thanks all for the help
There is no requirement from the standard that objects from the first range will only be passed as the left hand argument of the comparison function, nor that objects in the second range will only be passed as the right hand argument. So, what Visual Studio is doing is perfectly valid, and often necessary (see below).
What you can do is write a single functor that handles both cases:
template <class K,class P>
struct set_mapKey_less : public std::binary_function<K,P,bool>
{
inline bool operator() (const K& x, const P& y) const {return x < y.first;};
inline bool operator() (const P& y, const K& x) const {return y.first < x; }
};
...
std::map<int,int> m;
std::set<int> s;
std::includes(m.begin(), m.end(), s.begin(), s.end(),
set_mapKey_less<int,std::pair<int const,int> >());
To understand why the check that VS is doing might be necessary, consider the following:
set X = { 1000, 3000, 5000, 7000, 9000 }
map Y = { (3000,'a') }
How are you going to test whether X includes Y if all you have is an less than operator that takes a pair value on the left, and an integer on the right?
Is (3000,'a').first < 1000? No.
Is (3000,'a').first < 3000? No.
Is (3000,'a').first < 5000? Yes.
At this point, we know that (3000,'a').first, if in the set, has to be 3000. But how do we test that it actually is 3000 with a comparator that can only take the pair on the left side? If we can reverse the arguments, we can do it:
Is 3000 < (3000,'a').first? No.
So now we know that 3000 is not less than (3000,'a').first, and (3000,'a').first is not less than 3000, therefore they must be equal.

Non-type template function pointer to const member function

I'm writing a delegate class but it fails to take const member functions.
Here is a test case :
class foo
{
public:
void MemberFunction()
{
printf("non const member function\n");
}
void ConstMemberFunction() const
{
printf("const member function\n");
}
};
template <class C, void (C::*Function)()>
void Call(C* instance)
{
(instance->*Function)();
}
int main (int argc, char** argv)
{
foo bar;
Call<foo,&foo::MemberFunction>(&bar);
Call<foo,&foo::ConstMemberFunction>(&bar);
}
Now the compiler (visual studio 2010) gives me an error he cannot convert the const member function to a non-const function :
2>..\src\main.cpp(54): error C2440: 'specialization' : cannot convert from 'void (__cdecl foo::* )(void) const' to 'void (__cdecl foo::* const )(void)'
2> Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
2>..\src\main.cpp(54): error C2973: 'Call' : invalid template argument 'void (__cdecl foo::* )(void) const'
2> ..\src\main.cpp(37) : see declaration of 'Call'
ok, easy fix (I though :P ) by adding this :
template <class C, void (C::*Function)() const>
void Call(C* instance)
{
(instance->*Function)();
}
but now the compiler is completly confused (and me with it). it looks like he now tries to use the const function for the non-const member function and the non-const function for the const member function.
2>..\src\main.cpp(53): error C2440: 'specialization' : cannot convert from 'void (__cdecl foo::* )(void)' to 'void (__cdecl foo::* const )(void) const'
2> Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
2>..\src\main.cpp(53): error C2973: 'Call' : invalid template argument 'void (__cdecl foo::* )(void)'
2> ..\src\main.cpp(43) : see declaration of 'Call'
2>..\src\main.cpp(53): error C2668: 'Call' : ambiguous call to overloaded function
2> ..\src\main.cpp(43): could be 'void Call<foo,void foo::MemberFunction(void)>(C *)'
2> with
2> [
2> C=foo
2> ]
2> ..\src\main.cpp(37): or 'void Call<foo,void foo::MemberFunction(void)>(C *)'
2> with
2> [
2> C=foo
2> ]
2> while trying to match the argument list '(foo *)'
2>..\src\main.cpp(54): error C2440: 'specialization' : cannot convert from 'void (__cdecl foo::* )(void) const' to 'void (__cdecl foo::* const )(void)'
2> Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
2>..\src\main.cpp(54): error C2973: 'Call' : invalid template argument 'void (__cdecl foo::* )(void) const'
2> ..\src\main.cpp(37) : see declaration of 'Call'
2>..\src\main.cpp(54): error C2668: 'Call' : ambiguous call to overloaded function
2> ..\src\main.cpp(43): could be 'void Call<foo,void foo::ConstMemberFunction(void) const>(C *)'
2> with
2> [
2> C=foo
2> ]
2> ..\src\main.cpp(37): or 'void Call<foo,void foo::ConstMemberFunction(void) const>(C *)'
2> with
2> [
2> C=foo
2> ]
2> while trying to match the argument list '(foo *)'
If I would rename the second Call function (with the const), it all works fine but I would rather use one function.
So, can anybody point me towards what I'm doing wrong and how I can make this work ?
Thx!
I think you might be able to address this by removing the function pointer from the template type signature and instead relying on overloading:
template <class C>
void Call(C* ptr, void (C::*function)()) {
(ptr->*function)();
}
template <class C>
void Call(C* ptr, void (C::*function)() const) {
(ptr->*function)();
}
This now uses normal function overloading to select which of the two functions should be called. const member function pointers will call down to the second version, while non-const functions will call up to the first version. This also means that you don't need to explicitly provide any type information to the template function; the compiler can deduce C in both contexts.
Let me know if (1) this doesn't work or (2) this does work, but isn't what you want.
Hope this helps!
Use std::bind or lambdas, which VS2010 supports, and std::function and this will cease to be a problem for you.
Your problem is that a member function pointer is a different type than a const member function pointer. I modified your Call function to this:
template< typename C, typename funcptr_t, funcptr_t ptr >
void Call( C *instance )
{
(instance->*ptr)();
}
and now using the additional template parameter, I can call it like this:
Call<foo,void (foo::*)(),&foo::MemberFunction>(&bar);
Call<foo,void (foo::*)() const, &foo::ConstMemberFunction>(&bar);
That's a bit messy, though. The overloading solution is better! :-)