C++ error: no matching function for call to function template - c++

I have a function template that extracts data from an image and copies it to a smaller array (which I call a Patch) the template function is called copyPatch. It is defined as:
template <class DestType, class SrcType, class Transformation>
bool copyPatch(Patch<DestType> &patch,
ImageData<SrcType>* src_data,
size_t src_ul_pix,
size_t src_ul_line)
Note: the Transformation parameter allows me to pass in a class that performs some transformation on the data. I call the template function as follows,
copyPatch<float, uint8_t, StraightCopy>(m_patch_data, m_data.t8u,
ul_pix, ul_line)
where m_patch_data is of type Patch<float> and m_data.t8u is a member of a union defined as follows:
union {
ImageData<uint8_t>* t8u;
ImageData<uint16_t>* t16u;
ImageData<int16_t>* t16s;
ImageData<uint32_t>* t32u;
ImageData<int32_t>* t32s;
// A bunch more of these
void* tvoid;
} m_data;
When I compile this I get the following error (that I've doctored a bit):
error: no matching function for call to:
copyPatch(Patch<float>&, ImageData<unsigned char>*&, size_t&, size_t&)’
copyPatch<float, uint8_t, StraightCopy>( m_patch_data, m_data.t8u, ul_pix, ul_line);
^
note: candidate is:
template<class DestType, class SrcType, class Transformation>
bool copyPatch(Patch<T>&, ImageData<SrcType>*, size_t, size_t)
template argument deduction/substitution failed:
To me, I don't see why the function didn't match. The only possible reason I can see is that for the 2nd parameter it wants a pointer (which is what I thought I was passing), but the calling code seems to be passing a reference to a pointer.
Compiler is g++ 4.8.1.
As pointed out in the comments the problem possibly with my Transformation (StraightCopy) which is defined as follows:
template<class Dest, class Src>
class StraightCopy {
public:
Dest operator()(Src s) { return static_cast<Dest>(s); }
};
I missed passing the parameters to my StraightCopy class.

Thanks to PlasmaHH for pointing me in the right direction. My transformation type (StraightCopy) needed parameters. So my call looks like:
copyPatch<float, uint8_t, StraightCopy< float, uint8_t > >( m_patch_data, m_data.t8u, ul_pix, ul_line);
Isn't that beautiful :o)

Related

Member function pointer issue with standard library methods

This question is spawned from
Passing a member function pointer to an overloaded class method into a template function.
You need not read that to understand this question. Probably both the questions will have the same answer.
I am getting compiler error for below simple code.
#include<set>
template<typename Return, typename T>
T ReceiveFuncPtr (Return (T::*Method)(const int&))
{
T obj; // Found and declared an object of actual container class
(obj.*Method)(1); // Some processing
return obj; // Returned that container class object with RVO
}
int main ()
{
ReceiveFuncPtr(&std::set<int>::insert); // ERROR
}
The error is interesting:
In function 'int main()':
error: no matching function for call to 'ReceiveFuncPtr(<unresolved overloaded function type>)'
ReceiveFuncPtr(&std::set<int>::insert); // ERROR
^
note: candidate is:
note: template<class Return, class T> T ReceiveFuncPtr(Return (T::*)(const int&))
T ReceiveFuncPtr (Return (T::*Method)(const int&))
^
note: template argument deduction/substitution failed:
note: mismatched types 'const int&' and 'std::initializer_list<int>'
ReceiveFuncPtr(&std::set<int>::insert); // ERROR
^
note: mismatched types 'const int&' and 'std::set<int>::const_iterator {aka std::_Rb_tree_const_iterator<int>}'
note: mismatched types 'const int&' and 'std::set<int>::const_iterator {aka std::_Rb_tree_const_iterator<int>}'
note: mismatched types 'const int&' and 'std::set<int>::value_type&& {aka int&&}'
note: couldn't deduce template parameter 'Return'
If you look at the notes closely then it appears that compiler is matching all the other methods except the right one! In this case compiler should have matched insert(const std::set<int>::value_type&) aka const int&. If I change the ReceiveFuncPtr() to match some other overload, it will again fail by skipping that overload.
To debug this situation, I created handcrafted version of std::set. But that compiles fine:
template<typename T, typename T2 = void>
struct MySet
{
std::pair<T,bool> insert (const T& i) { return std::pair<T,bool>(T(),true); }
std::pair<T,bool> insert (T&& i) { return std::pair<T,bool>(T(),true); }
void insert (std::initializer_list<T> i) { return false; }
}
int main ()
{
ReceiveFuncPtr(&MySet<int>::insert); // OK
}
After surfing, I came across this post:
What are the rules for function pointers and member function pointers to Standard functions?
Though it's related , it doesn't solve problem.
Question: Why member function substitution fails in case of standard library method when the the same thing passes for handwritten class method?
Update:
After looking at the correct answer, I am sure that insert cannot be used. The only way would be ugly typecasting which is an overkill for this problem.
One elegant solution is to use std::set<int>::emplace<const int&> which has only templated version unlike insert which has mix of template and non-template versions.
Call the function as below:
ReceiveFuncPtr(&std::set<int>::emplace<const int&>);
Above compiles fine.
The problem isn't with the insert functions you showed in MySet. The problem is with one of the ones you omitted. Specifically:
template< class InputIt >
void insert( InputIt first, InputIt last );
From [temp.deduct.call]:
When P is a function type, pointer to function type, or pointer to member function type:
— If the argument is an overload set containing one or more function templates, the parameter is treated
as a non-deduced context.
Since &std::set<int>::insert is precisely such an overload set, the parameter is a non-deduced context and cannot be resolved. Your example of MySet does not contain a function template overload for insert, which is why it works fine. If you add one, you'll see that it will also fail to compile.

Passing a member function pointer to an overloaded class method into a template function [duplicate]

This question is spawned from
Passing a member function pointer to an overloaded class method into a template function.
You need not read that to understand this question. Probably both the questions will have the same answer.
I am getting compiler error for below simple code.
#include<set>
template<typename Return, typename T>
T ReceiveFuncPtr (Return (T::*Method)(const int&))
{
T obj; // Found and declared an object of actual container class
(obj.*Method)(1); // Some processing
return obj; // Returned that container class object with RVO
}
int main ()
{
ReceiveFuncPtr(&std::set<int>::insert); // ERROR
}
The error is interesting:
In function 'int main()':
error: no matching function for call to 'ReceiveFuncPtr(<unresolved overloaded function type>)'
ReceiveFuncPtr(&std::set<int>::insert); // ERROR
^
note: candidate is:
note: template<class Return, class T> T ReceiveFuncPtr(Return (T::*)(const int&))
T ReceiveFuncPtr (Return (T::*Method)(const int&))
^
note: template argument deduction/substitution failed:
note: mismatched types 'const int&' and 'std::initializer_list<int>'
ReceiveFuncPtr(&std::set<int>::insert); // ERROR
^
note: mismatched types 'const int&' and 'std::set<int>::const_iterator {aka std::_Rb_tree_const_iterator<int>}'
note: mismatched types 'const int&' and 'std::set<int>::const_iterator {aka std::_Rb_tree_const_iterator<int>}'
note: mismatched types 'const int&' and 'std::set<int>::value_type&& {aka int&&}'
note: couldn't deduce template parameter 'Return'
If you look at the notes closely then it appears that compiler is matching all the other methods except the right one! In this case compiler should have matched insert(const std::set<int>::value_type&) aka const int&. If I change the ReceiveFuncPtr() to match some other overload, it will again fail by skipping that overload.
To debug this situation, I created handcrafted version of std::set. But that compiles fine:
template<typename T, typename T2 = void>
struct MySet
{
std::pair<T,bool> insert (const T& i) { return std::pair<T,bool>(T(),true); }
std::pair<T,bool> insert (T&& i) { return std::pair<T,bool>(T(),true); }
void insert (std::initializer_list<T> i) { return false; }
}
int main ()
{
ReceiveFuncPtr(&MySet<int>::insert); // OK
}
After surfing, I came across this post:
What are the rules for function pointers and member function pointers to Standard functions?
Though it's related , it doesn't solve problem.
Question: Why member function substitution fails in case of standard library method when the the same thing passes for handwritten class method?
Update:
After looking at the correct answer, I am sure that insert cannot be used. The only way would be ugly typecasting which is an overkill for this problem.
One elegant solution is to use std::set<int>::emplace<const int&> which has only templated version unlike insert which has mix of template and non-template versions.
Call the function as below:
ReceiveFuncPtr(&std::set<int>::emplace<const int&>);
Above compiles fine.
The problem isn't with the insert functions you showed in MySet. The problem is with one of the ones you omitted. Specifically:
template< class InputIt >
void insert( InputIt first, InputIt last );
From [temp.deduct.call]:
When P is a function type, pointer to function type, or pointer to member function type:
— If the argument is an overload set containing one or more function templates, the parameter is treated
as a non-deduced context.
Since &std::set<int>::insert is precisely such an overload set, the parameter is a non-deduced context and cannot be resolved. Your example of MySet does not contain a function template overload for insert, which is why it works fine. If you add one, you'll see that it will also fail to compile.

Function pointer to boost::geometry function

I'm trying to pass the boost::geometry::get function described here to another function, but I can't seem to get it right.
I have:
template<typename StorageType = double,
std::size_t D = 3>
class Derivative : public DerivativeBase<StorageType, D> {
public:
typedef typename DerivativeBase<StorageType, D>::results_t results_t;
template<typename Iterator, typename Geometry>
results_t operator()(Iterator& objIterator, StorageType (*getter)(Geometry const&))
...
and the compiler throws:
error: no match for call to ‘(Derivative<double, 3ul>) (iterator&, <unresolved overloaded function type>)’
I tried calling my function with:
derivs = myDerivs(it, &boost::geometry::get<0>);
I guess part of the issue is that since I don't pass an argument to get, the compiler can't figure out what type Geometry should be in the function signature.
How do I go about passing this function through?
This is entirely non-specific to boost.geometry. You need to static_cast the function to it's exact type if it is overloaded or you need to pass all template parameters explicitly. The second is the case here (e.g. &get<0, GeometryType>).

using templates with vectors and vector functions

I am attempting to template a vector. In my main I have the following:
std::vector<Word> concordance = push_vector(data);
Where Word is a struct containing a std::string and an int, and data is a std::string. In my header file I have:
template <typename T>
std::vector<T> push_vector(std::string&);
However when I compile I get the following error:
main.cpp: In function ‘int main(int, char**)’:
main.cpp:27:53: error: no matching function for call to ‘push_vector(std::string&)’
main.cpp:27:53: note: candidate is:
templates.h:13:20: note: template<class T> std::vector<T> push_vector(std::string&)
I know I am missing something when I am implementing my template function, but I am not sure what. Thank you for your time in advance.
If I understand what you actually want to do perhaps something more like this:
template <typename T>
void push_vector(const std::string& str, std::vector<T>& vec)
{
// convert str to T if possible
// throw on failure maybe?
// assign vec with converted data
}
Then call it like so:
std::string data("Hello");
std::vector<Word> concordance;
push_vector(data, concordance);
Otherwise you would have to explicitly give the function it's template argument as it can't deduce from the rvalue you are assigning the return value into what the type should be. Not too mention passing an out paramater by reference like this saves you some performance.
Try:
std::vector<Word> concordance = push_vector<Word>(data);
The compiler can't resolve it without a hint because you don't use T anywhere other than the return value. Usually, the template parameter is also used as the type of one (or more) of the template functions' parameters, and then the compiler would be able to resolve it directly.

pointer assignment

I have the following template structure:
template <typename scalar_type>
struct postc_params{
scalar_type delta;
unsigned int time_horizon;
matrix_math::matrix<scalar_type> dynamics;
boost::shared_ptr<continuous_set> invariant_set_ptr;
boost::shared_ptr<continuous_set> input_set_ptr;
boost::shared_ptr<continuous_set> initial_set_ptr;
};
Now, I have a templated class with a private member of the above structure type
template <typename scalar_type>
class A{
....
private:
....
postc_params<scalar_type> my_postc;
};
Inside a member function definition of class A, I have the following line of code:
my_postc.initial_set_ptr = my_postc.initial_set_ptr->transform(some_obj);
transform function returns a pointer of type
boost::shared_ptr<continuous_set>
With this code, I have the following error:
passing 'const boost::shared_ptr' as 'this' argument of 'boost::shared_ptr< >& boost::shared_ptr< >::operator=
(const boost::shared_ptr&) [with Y = const continuous::continuous_set, T = continuous::continuous_set]' discards qualifiers
Can anyone help me out with the cause?
Is the member function in A const?
If I am reading your code right, you are trying to change a member of a class from a const member function which is not allowed. Either remove the const from the member function or make the member mutable.
So,
mutable postc_params<scalar_type> my_postc;
However, I would take care with this method. Maybe reevaluate why the method that is changing my_postc is const. Either it should not be const or it should not be changing my_postc.
you are trying to assign to a const pointer as per the error message: "passing 'const boost::shared_ptr' as 'this' argument"
the member function you mention is surely const hence the error
you should rather reconsider your design than throw mutable here and there in your code.