I have a member function of a template class declared as such:
template <class T>
int Data<T>::getPosition(vector<T> stuff, T newStuff, bool ascending)
I call this somewhere with the line
frequencies.insert(frequencies.begin() + getPosition(frequencies, current, ascending),
frequencies[i]);
The variables for that line are declared as:
vector<T> temp;
vector<int> frequencies;
int current = frequency.find(words[i])->second;
However, the call to getPosition gives this error:
Data.h|158|error: no matching function for call to 'primitives::Data<double>::getPosition(std::vector<int, std::allocator<int> >&, int&, bool&)'|
Data.h|165|note: candidates are: int primitives::Data<T>::getPosition(std::vector<T, std::allocator<_CharT> >, T, bool) [with T = double]|
What am I doing wrong here?
getPosition takes three arguments of type vector<T>, T and bool. The templated type T in this case is double (as is shown in the error message), and yet you are trying to pass vector<int> and int as the first and second argument, respectively.
Perhaps the parameters for getPosition should not be templated? Depends on what you are trying to achieve - you do have hard-coded int-vectors there, after all.
Your function prototype gets templated on Data<t>, and it looks like you're performing this call on an object with type Data<double> and passing a std::vector<int> and an int, when it probably expects a std::vector<double> and a double to correspond to the initial templated type of the Data object.
vector<T> temp;
Shouldn't T here be some type like int, double or bool?
Related
We have a question, which discusses how to use a comparator in priority_queue in C++. He gives the overloaded operator class (or struct) as the third argument and it works fine. But bool function doesn't work. Why ? But it works fine in sort of the <algorithm>. When I looked into docs (priority_queue && algo/sort), both of them take the class Compare as their optional third argument.
#include <iostream>
#include <cstdio>
#include <queue>
#include <algorithm>
#include <vector>
using namespace std;
bool cmp (const int &a,const int &b){ return a > b; }
struct cmp2
{
bool operator() (const int &p1,const int &p2)
{
return p1 > p2;
}
};
int main ()
{
// freopen("test.txt","r",stdin);
int a[10];
vector<int> b(10);
sort( a , a + 10, cmp ); // working cool
sort( b.begin() , b.end() , cmp); // working great
priority_queue<int, vector<int> , cmp2 > x; // as usual, working....
priority_queue<int, vector<int> , cmp > y; // not working why ?
return 0;
}
Errors:
A:\pqvsarray.cpp In function 'int main()':
27 40 A:\pqvsarray.cpp [Error] type/value mismatch at argument 3 in template parameter list for 'template<class _Tp, class _Sequence, class _Compare> class std::priority_queue'
27 40 A:\pqvsarray.cpp [Error] expected a type, got 'cmp'
27 43 A:\pqvsarray.cpp [Error] invalid type in declaration before ';' token
So, why the difference ?
You can use a function with std::priority_queue as well. The difference in what you're doing is that you pass the function to std::sort as a function parameter, but you try to define the function as a template parameter of the queue. This obviously does not work because the third argument is a type argument as the error explains. Besides, you cannot even have pointer or reference template arguments.
If you take a look at the reference, you'll find that the queue has a constructor for passing the comparison object. That's where you must pass the function.
There is a difference with std::sort. Sort is a function, and you can let the compiler deduce it's template arguments so you don't have to specify them explicitly. The queue is a class template, and template arguments of a class template can not be deduced (not in this context at least).
The template argument is defaulted to std::less<typename Container::value_type>, but you don't want to use that. Therefore, you must specify explicitly the type of the comparison object. You specify it where you're now trying to pass the object. How to get the type of the function pointer/reference, you may ask. You can do it like this: decltype(&cmp). If you have an outdated compiler that does not support decltype yet, then you'll need to specify the type without it: bool (&)(const int&, const int&).
Here is an example of how you would create a queue that uses your function.
std::priority_queue<int, std::vector<int>, decltype(&cmp)> x(cmp);
As the error message implies, functions cannot be used as template parameters. The priority_queue will copy an object of the comparison type. For example, this might be std::less<int>, where an object of that type is std::less<int>(), and it being called is std::less<int>()(x, y). In C++11, you could use decltype, but in C++03 the "canonical" way is to create a "functor" (an entire type dedicated to being used as a function object.) This is one of the reasons why lambdas were created.
The answer is in compiler errors.
The third template parameter of priority queue is a comparator type (like structure or classes) and not a function.
I have the following piece of code:
#include <functional>
template <typename T>
class TD; // For displaying type
void f(int, int, int) { }
int main() {
auto g = std::bind(f, std::placeholders::_1, 2, 2);
TD<decltype(g)> td1;
return 0;
}
In this code TD is a template trick for showing its template argument passed via decltype.
Output of the compiler follows (compiled in C++14 mode):
prog.cpp: In function 'int main()':
prog.cpp:10:18: error: aggregate 'TD<std::_Bind<void (*(std::_Placeholder<1>, int, int))(int, int, int)> > td1' has incomplete type and cannot be defined
TD<decltype(g)> td1;
^
Well, incomplete type error is of course excepted. But what makes me curious in this error message is std::_Bind<void (*(std::_Placeholder<1>, int, int))(int, int, int)>. I can comprehend that std::_Bind is a proxy class which defines operator() and makes our purpose possible. But its template argument void (*(std::_Placeholder<1>, int, int))(int, int, int) made me woow! How should I interpret it? Does it have any usefulness in user-land code? How can I create my own classes making use of this declaration?
void (*(std::_Placeholder<1>, int, int))(int, int, int)
This declares an unnamed function taking three parameters (std::_Placeholder<1>, int and int) and returning a pointer to a function that takes three ints and returns void.
Let's simplify a little. First consider a simple function declaration:
void f(int)
Now, in parameter declarations (of functions or templates) you can omit the name and you get
void (int)
which, if used in a parameter list of a function declaration, would be equivalent to a function pointer void(*)(int).
A function that returns a function pointer is declared like this:
void (*f(int))(int);
// ^ ^ <- this pair of parentheses changes
// the order in which the declaration is parsed.
// Without it, the return type would be `void*`
// and you'd get a syntax error
Now you can remove the name f and you basically get the same thing that you were asking about.
Its uses? Apparently it's useful when implementing std::bind :) I can't think of anything else right now...
C++11 marked the advent of function which made defining function pointers far easier:
Instances of std::function can store, copy, and invoke any Callable target -- functions, lambda expressions, bind expressions, or other function objects, as well as pointers to member functions and pointers to data members.
So for example let's say that you needed to take in a function pointer to string foo(int param) { return to_string(param); } in one of your functions. Pre-C++11, your function would need to look like:
void bar(string (*func)(int)) { cout << func(13) << endl; }
Let's go a step further and say you wanted to expand foo to: string foo2(int lhs, int rhs) { return to_string(lhs + rhs); }. But now you want to cram that back into bar. Doing this bar(bind(&foo2, placeholders::_1, 42)); would give you an error like this:
cannot convert 'std::_Bind_helper (*)(int, int), const std::_Placeholder<1>&, int>::type {aka std::_Bind (*(std::_Placeholder<1>, int))(int, int)>}' to 'std::string (*)(int) {aka std::basic_string (*)(int)}' for argument '1' to 'void bar(std::string (*)(int))'
You could get around this error by creating a function that took an implementation specific argument, like: void bar2(_Bind<string (*(_Placeholder<1>, int))(int, int)> func) { cout << func(13) << endl; } which could successfully be called with: bar2(bind(&foo2, placeholders::_1, 42));. The reason that this is implementation specific is that the types: _Bind and _Placeholder are non-standard. In fact the return of bind is:
A function object of unspecified type T
Which brings us to function. If you weren't already turned off by the syntax the limitations of a function pointer, you'll need to take a function parameter to accept an object created by bind. Let's make a new bar using function:
void bar3(function<string(int)> func) { cout << func(13) << endl; }
This is capable of accepting both the traditional function pointer and the bind functor. Additionally it can handle lambdas, so you can do this: bar3([](int param) { return to_string(param); });
I've created a live example so you can play around with this some hopefully the benefits of the function object are clear.
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)
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>).
I define a template function which loads a map from a CSV file:
template <class T>
bool loadCSV (QString filename, map<T,int> &mapping){
// function here
}
I then try to use it:
map<int, int> bw;
loadCSV<int>((const QString)"mycsv.csv",&bw);
But get htis compile time error:
error: no matching function for call to
‘loadCSV(const QString, std::map<int, int, std::less<int>, std::allocator<std::pair<const int, int> > >*)’
It seems my function call is bringing in some implicit arguments, but I don't understand the error and how to fix it. Any ideas?
Drop the ampersand, you don't want to pass a pointer to the map (notice the asterisk at the end of the error message). Also, you don't have to explicitly cast the string literal. Moreover, the compiler should be able to deduce the template argument automatically.
loadCSV("mycsv.csv", bw);