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.
Related
This question already has answers here:
C++ overloaded function as template argument
(4 answers)
Closed 6 years ago.
I want to use some predefined comparators as an argument for a template function.
A code skeleton:
struct Line
{
double length() const;
// some data
};
struct Square
{
double area() const;
// some data
};
bool customCompare(const Line& a1, const Line& a2) { return a1.length() < a2.length(); }
bool customCompare(const Square& b1, const Square& b2) { return b1.area() < b2.area(); }
template <typename Comparator>
double calculateSomething(Comparator&& tieBreaker)
{
Line l1, l2;
return tiebreaker(l1, l2) ? l1.length() : l2.length();
}
auto result = calculateSomething(customCompare);
However, my compiler (VS12 update 5) gives the following compile errors
error C2914: 'calculateSomething' : cannot deduce template argument as function argument is ambiguous
error C2784: 'double calculateSomething(Comparator &&)' : could not deduce template argument for 'overloaded function type' from 'overloaded function type'
Clearly, what I want to do is to specify the comparator more precisely, like
auto result = calculateSomething(customCompare(const Line&, const Line&));
But this is also not allowed...
how to solve this ? (I know I can resort to a lambda, but is there another way ?)
Specify the template parameter type explicitly, like this:
auto result = calculateSomething<bool(const Line&,const Line&)>(customCompare);
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.
My code is :
std::vector<double> Vec;
template<typename T>
void GetObj(VARIANT &vtProp)
{
CComSafeArray<T> SafeArray;
SafeArray.Attach(vtProp.parray);
ULONG Count = SafeArray.GetCount();
Vec.resize(Count);
for(ULONG Index = 0; Index < Count; Index++)
{
Vec[Index] = SafeArray[Index];
}
}
while compilation I got the error below:
error C2783: 'void __cdecl GetObj(struct tagVARIANT &)' : could not deduce template argument for 'T'
Kindly suggest me the correct answer
There is nothing in the function template's signature that allows the compiler to deduce the template type, so you need to be explicit:
GetObj<TheActualType>(arg);
I'm trying to overload a Sum function which accepts a [list or vector] start and end iterator as arguments. This compiler error is really confusing me. Relevant code is as follows:
template <typename T1, typename T2>
const double Sum(const typename T1::const_iterator& start_iter, const typename T2::const_iterator& end_iter)
{// overloaded function that calculates sum between two iterators
typename T1::const_iterator iterator_begin = start_iter;
typename T2::const_iterator iterator_end = end_iter;
double my_sum = 0;
for (iterator_begin; iterator_begin != iterator_end; iterator_begin++)
my_sum += *iterator_begin;
return my_sum;
}
int main()
{
list<double> test_list(10,5.1);
cout << Sum(test_list.begin(), test_list.end()); // compiler errors here
}
I get the following compiler errors:
iterators.cpp(72): error C2783: 'const double Sum(const
T1::const_iterator &,const T2::const_iterator &)' : could not deduce
template argument for 'T1'
iterators.cpp(72): error C2783: 'const double Sum(const
T1::const_iterator &,const T2::const_iterator &)' : could not deduce
template argument for 'T2'
iterators.cpp(72): error C2780: 'const double Sum(const
std::map &)' : expects 1 arguments - 2 provided
iterators.cpp(72): error C2780: 'const double Sum(const T &)' :
expects 1 arguments - 2 provided
How is the compiler not recognizing I'm trying to call the Sum function with two inputs? I'm calling the function incorrectly?
Thanks!
You dont need to tell it that iterators have to be members of some types T1 and T2, just template it on iterator type itself:
template <typename Iter>
const double Sum(Iter iterator_begin, Iter iterator_end)
{
double my_sum = 0;
for (; iterator_begin != iterator_end; ++iterator_end)
my_sum += *iterator_begin;
return my_sum;
}
int main()
{
std::list<double> test_list;
std::cout << Sum(test_list.begin(), test_list.end());
return 0;
}
also there is a standard std::accumulate that does this:
int main()
{
std::list<double> test_list;
std::cout << std::accumulate(test_list.begin(), test_list.end(), 0.0);
return 0;
}
First, I don't think you want to do this. Not all sequences have an
underlying container. (Think of istream_iterators, for example.) And
more importantly, you're distinctly allowing (and even encouraging)
begin and end iterators from different containers; there is no case
where you could legally use this function where T1 and T2 have
different types. The template should have a single parameter, which
should be an iterator; and by convention, the constraints on the
iterator should be expressed in the name of the parameter, e.g.
InputIterator (the case here), ForwardIterator, etc.
As to why your code doesn't compile:
In most cases, the types, templates, and non-type values that are used
to compose P participate in template argument deduction. That is, they
may be used to determine the value of a template argument, and the
value so determined must be consistent with the values determined
elsewhere. In certain contexts, however, the value does not
participate in type deduction, but instead uses the values of template
arguments that were either deduced elsewhere or explicitly specified.
If a template parameter is used only in non-deduced contexts and is
not explicitly specified, template argument deduction fails.
The non-deduced contexts are:
— The nested-name-specifier of a type that was specified using a
qualified-id.
[...]
(From §14.8.2.5/4,5.)
Call method like this..
Sum<list<double>,list<double> >(test_list.begin(), test_list.begin());
I have written a sort class to sort the multimap, but when I insert element into the map, the following compiler error appears:
1>c:\program files\microsoft visual studio 9.0\vc\include\xutility(313) : error C2664: 'bool MapSort::operator ()(std::pair<_Ty1,_Ty2> &,std::pair<_Ty1,_Ty2> &)' : cannot convert parameter 1 from 'const std::pair<_Ty1,_Ty2>' to 'std::pair<_Ty1,_Ty2> &'
can anybody help?
class MapSort
{
public:
MapSort();
~MapSort();
public:
bool operator() ( pair<T,T>& i, pair<T,T>& j)
{
return i.first.GetID() < j.first.GetID();
}
};
multimap < pair < T,T >,P > CurrMap;
CurrMap.insert( multimap < pair < T, T >,Metric >::value_type(make_pair< T,T >(aAttractionA,aAttractionB),CurrP))
//
pair<T,T>& i and pair<T,T>& j
should be
pair<T,T> const& i and pair<T,T> const& j
(reference)
You forgot const-correctness:
bool operator()(pair<T,T> const& i, pair<T,T> const& j) const
{
return i.first.GetID() < j.first.GetID();
}
Nothing in this function needs to be mutable, so "why not" make the function and its inputs const?
In fact, this is expected of you by the contracts of the container.
In addition, I'm not sure that your own sort ordering here is valid or that it makes sense. It certainly doesn't seem entirely purposeful. pair<T,T> already sorts naturally: if anything, you might have a bool operator< for your type T.
Your sort predicate must take const references.
Plus, aren't multi-maps already sorted?