Two parameter template acting differently from one parameter in call - c++

For an assignment (this is a fairly small part I've been stuck on, I'm not asking for anyone to do the homework), we were supplied with the following code and its call in the main file:
template <class number_type>
class Point {
public:
Point(const number_type& x_, const number_type& y_) : x(x_),y(y_) {}
// REPRESENTATION
number_type x;
number_type y;
};
template <class number_type, class label_type>
class QuadTree {
public:
QuadTree(const number_type& number_, const label_type& label_) : number(number_), label(label_){}
number_type number;
label_type label;
};
int main() {
std::vector< std::pair<Point<int>,char> > simple_points;
QuadTree<int,char> simple;
}
However, using a very similar style to the supplied coding produces a "no matching function" error in my terminal:
I'm confused as to why it doesnt work in this case, as well as what I can do to fix it.
As a note, we are not allowed to use c++11, structs, and a few other tools. Also, we are not permitted to change anything in the "main" function, so QuadTree simple; MUST stay as-is
main.cpp: In function ‘void simple_test()’:
main.cpp:110:22: error: no matching function for call to ‘QuadTree<int, char>::QuadTree()’
QuadTree<int,char> simple;
^
main.cpp:110:22: note: candidates are:
In file included from main.cpp:14:0:
quad_tree.h:56:5: note: QuadTree<number_type, label_type>::QuadTree(const number_type&, const label_type&) [with number_type = int; label_type = char]
QuadTree(const number_type& number_, const label_type& label_) : number(number_), label(label_){}
^
quad_tree.h:56:5: note: candidate expects 2 arguments, 0 provided
quad_tree.h:54:7: note: QuadTree<int, char>::QuadTree(const QuadTree<int, char>&)
class QuadTree {
^
quad_tree.h:54:7: note: candidate expects 1 argument, 0 provided

This code:
QuadTree<int,char> simple;
is attempting to call the default constructor. However, since you provide a constructor, the default constructor is implicitly deleted. The constructor you provided is:
QuadTree(const number_type& number_, const label_type& label_)
So you'd have to do:
QuadTree<int, char> simple(42, 'C');

Your QuadTree constructor takes 2 parameters, but you probably (based on your error message) have a definition like
QuadTree<int,char> simple;
which declares an object with no parameters passed to the constructor. You need to do something like
QuadTree<int, char> simple(2, 'a'); // need to specify the parameters
Note that because you defined a constructor, the compiler does not generate a default one for you anymore.

Related

C++ more than one instance of overloaded function matches the argument list when creating a header file

Within my main file of my program I have the following declarations
int main()
{
Customer c;
Part p;
Builder b;
auto partsVec = readpartFile();
auto customerVec = readcustomerFile();
auto builderVec = readbuilderFile();
fexists("Parts.txt");
complexity(c, partsVec);
robotComplexity(partsVec,customerVec);
writeFile(buildAttempt(b, complexity(c, partsVec), variability(customerVec, builderVec)));
}
My header file consists of the following
vector<Part> readpartFile();
vector<Customer> readcustomerFile();
vector<Builder> readbuilderFile();
float complexity(const Customer& c, const std::vector<Part>& parts);
void robotComplexity(vector<Part> vecB, vector<Customer> vecC);
double variability(const vector<Customer>& customerList, const vector<Builder>& builderList);
vector<double> buildAttempt(Builder b, double variaiblity, double complexityRobot);
void writeFile(vector<double> build);
All functions link up except for robotComplexity. My declaration of this function in main creates the following error.
more than one instance of overloaded function "robotComplexity" matches the argument list: -- function "robotComplexity(const std::vector> &parts, const std::vector> &customers)" -- function "robotComplexity(std::vector> vecB, std::vector> vecC)" -- argument types are: (std::vector>, std::vector>)
im not sure why im getting this error or how to resolve it
You have a mismatch between declaration in header and definition (which also serves as declaration):
void robotComplexity(vector<Part> vecB, vector<Customer> vecC);
void robotComplexity(const vector<Part>& vecB, const vector<Customer>& vecC);
Whereas parameter names can mismatch, types shouldn't, else, you create another overload.
Jarod42's Answer is quite correct, but I want to add to it and provide a helpful methodology for future C++ coding.
When function signatures differ, the compiler will not complain. At best, you will receive a cryptic or hard to read linker error. This is especially common with inheritance and virtual functions. Even worse, sometimes they will work but actually call a new function with a different signature on a child class that doesn't match the base class.
There is a keyword in C++11 (and newer versions) called override. Here is a more in depth discussion about what they keyword does: OverrideKeywordLink
When this keyword is used on a virtual function, it becomes a compile error when the intended virtual function override does not match the base class function signature. Also, it gives a very human readable reason why the function override did not occur.
You mentioned in a comment that 'How come const made it different"? The answer is it all comes down to function signatures. Consider these two functions within a class.
class MyClass {
int CalculateSomething();
int CalculateSomething() const;
}
The const actually changes the function signature. They are considered two different functions. The bottom line is, always try to make errors compile errors over run-time errors. Use keywords that protect you from some few tribal C++ knowledge traps that exist.

Compilation error when trying to use OpenCV Kalman Filter and template parameters, seems to not recognize cv::Matt

I've created a class that has an OpenCV KalmanFilter inside of it (OpenCV 2.4 if anyone's wondering). Without any template parameters, it compiles just fine.
class ClassOkay
{
public:
struct ClassState
{
cv::KalmanFilter kalmanFilter;
double time;
};
void doSomething();
private:
ClassState state;
};
void ClassOkay::doSomething()
{
//Okay
cv::Mat& x = state.kalmanFilter.statePost;
x.at<double>(0) = 5;
//Okay
state.kalmanFilter.statePost.at<double>(0) = 5;
}
Now when I add a template parameter, although here there are no objects with this template typename, it no longer compiles.
template<typename SubState>
class ClassNotOkay
{
public:
struct ClassState
{
cv::KalmanFilter kalmanFilter;
double time;
};
void doSomething();
private:
ClassState state;
};
template<typename SubState>
void ClassNotOkay<SubState>::doSomething()
{
//Okay
cv::Mat& x = state.kalmanFilter.statePost;
x.at<double>(0) = 5;
//Not okay
state.kalmanFilter.statePost.at<double>(0) = 5;
}
The very last line where I try to access statePost, it seems to not recognize it as a cv::Mat. The compiler error is as follows:
../Base.h: In member function ‘void ClassNotOkay<SubState>::doSomething()’:
../Base.h:169:37: error: expected primary-expression before ‘double’
state.kalmanFilter.statePost.at<double>(0) = 5;
^
../Base.h:169:37: error: expected ‘;’ before ‘double’
It seems really weird to me that it no longer understands that at is a method of statePost. Any ideas why and how this is happening?
OK, so I'm no expert, but I think I get the gist of what's happening now. Name lookup can be complex in template classes and functions because of the potential for names that are dependent on the template. (I.e., it may be impossible to determine whether a name referenced inside of a template function or class is a type or a template name or neither when it is first parsed.)
As a result, under some circumstances it is necessary to explicitly tell the compiler when a name is a template or type name. In this example, the compiler is not sure how to resolve at<double>. Presumably, this is because the compiler mistakenly believes that it could depend on the specific template parameter (SubState). I'm not sure whether that could be considered a bug - it may just be that the compiler is deliberately conservative wrt name lookup.
Anyway, you can resolve the compiler error by explicitly indicating that at<double> is a template:
state.kalmanFilter.statePost.template at<double>(0) = 5;

Adding class object in stl map as a value

I want to add class object in STL map as a value in C++.It's like std::map<CString,class myClass*>myMap. But compilers showing me error in doing this. Should I have to implement all comparison operators overloading for that class?? If not then how do I can achieve that?
Code is as follows:
// header file
#pragma once
#include "afxsock.h"
#include"NetworkDataProcessor.h"
#include"MainFrm.h"
#include"ChattingDialog.h"
#include<map>
using namespace std;
class CConnectionManager :public CAsyncSocket
{
public:
static CConnectionManager *GetClientInstance();
BOOL ClientSignIn(CString, CString);
void ConnectToServer();
public:
CString m_sendBuffer;
int m_nBytesSent;
int m_nBytesBufferSize = MAX_BUFFER_SIZE;
virtual void OnClose(int nErrorCode);
virtual void OnConnect(int nErrorCode);
virtual void OnReceive(int nErrorCode);
virtual void OnSend(int nErrorCode);
public:
std::map<CString, CChattingDialog* >ChatWindows;
private:`enter code here`
CConnectionManager();
~CConnectionManager();
static CConnectionManager * client_instance;
};
// cpp file function:
void CMyMessangerView::OnClientListClick(NMHDR* pnmh, LRESULT* pResult)
{
DWORD dwPos = ::GetMessagePos();
CPoint point((int)LOWORD(dwPos), (int)HIWORD(dwPos));
GetListCtrl().ScreenToClient(&point); int nIndex; if ((nIndex = GetListCtrl().HitTest(point)) != -1)
{
CString string = GetListCtrl().GetItemText(nIndex, 0);
CChattingDialog chatingDlg;
chatingDlg.SendToUser = string;
CString user = chatingDlg.UserRealName(string);
CConnectionManager *client = CConnectionManager::GetClientInstance();
client->ChatWindows.insert(pair<CString, CChattingDialog *>(user, &chatingDlg));
UpdateData(FALSE);
chatingDlg.DoModal();
}
*pResult = 0;
}
ERRORS:
15 IntelliSense: no instance of overloaded function "std::map<_Kty, _Ty, _Pr, _Alloc>::insert [with _Kty=CString, _Ty=CChattingDialog *, _Pr=std::less, _Alloc=std::allocator>]" matches the argument list
argument types are: (std::pair)
object type is: std::map, std::allocator>
Error 3 error C2976: 'std::map' : too few template arguments c:\projects\poc\mymessanger\mymessanger\clientconnection.h 25 1 MyMessanger
Error 4 error C2665: 'std::pair::pair' : none of the 3 overloads could convert all the argument types c:\projects\poc\mymessanger\mymessanger\mymessangerview.cpp 131 1 MyMessanger
16 IntelliSense: no instance of constructor "std::pair<_Ty1, _Ty2>::pair [with _Ty1=CString, _Ty2=CChattingDialog &]" matches the argument list
argument types are: (CString, CChattingDialog *) c:\Projects\POC\MyMessanger\MyMessanger\MyMessangerView.cpp 131 29 MyMessanger
etc... few more errors like indicating the same
Thanks everyone for responding to this problem. Thank you Fomin Arseniy.
The solution to this problem is what I guessed in the question and Fomin Arseniy said above.
We must have to overload at least Copy constructor and assigning operator for class we are going to use in map as a value.
First ,map declaration for user defined data types needs to be like
std::map<CString, class CChattingDialog> ChatWindows;
instead of
std::map<CString, CChattingDialog> ChatWindows;
and second,I added two functions
CChattingDialog& operator=(const CChattingDialog &s);
CChattingDialog(const CChattingDialog &s);
in the class CChattingDialog . Used inserting method as advised by Fomin Arseniy.
client->ChatWindows[user] = &chatingDlg;
compiled the code successfully.
We must have to provide public constructor, copy constructor, desctructor, assining operator and operator< (less than) if need to add user defined data types in STL map.
You use std::map in wrong way. You should rewrite your code as follows:
client->ChatWindows[user] = &chatingDlg;
(If you want to use map::insert method you can read about it here: http://www.cplusplus.com/reference/map/map/insert/. There is no pair inserting as you do, there is one method that returns pair of interator/succes).
However, you also asked what do you need to implement in your class to store it in map not by pointer but by value as:
std::map<CString, CChattingDialog> ChatWindows;
Correct answer is: you need public constructor, copy constructor, desctructor, assining operator and operator< (less than) in class CChattingDialog but not in class CConnectionManager.
Map uses them to have possibility to correctly store, copy, delete and sort elements of this class in it.

Passing this to an object within an object during the constructor call

I am trying to iron out my first compile in a long time, and I think this is the last hurdle.
I am trying to create this type of hierarchy in my design.
class chin_
{
private:
charon_* engine;
public:
chin_();
chin_(charon_ &handle)
{
engine = handle;
}
~chin_();
};
//////////////
class charon_ {
private:
chin_ engine_input;
public:
charon_(){
engine_input = chin_(this);
}
~charon_();
};
I am getting errors that tell me there is no matching function for call to
'chio::chin_::chin()'
it also says, mind you this is only when I change the constructor to charon_&
public:
chin_(const charon_ &handle)
{
engine = handle;
}
sys/../headers/chio.h:104:5: note: no known conversion for argument 1 from ‘charon::charon_* const’ to ‘const charon::charon_&’
When I use the * instead of & I get this instead, which is by far more baffling.
sys/../headers/chio.h:104:5: note: chio::chin_::chin_(const charon::charon_*)
sys/../headers/chio.h:104:5: note: candidate expects 1 argument, 0 provided
I've tried this and that, and I figure it is probably something super simple. I've tried to match my code up squarely with the examples I've found though so I don't know what else I should be trying, I'd like to be able to figure this sort of stuff out on my own. I just am not having any luck with it.
EDIT:
I update the code but I left the updated error for the bottom.
sys/chin.cpp:19:14: error: cannot convert ‘charon::charon_’ to ‘charon::charon_*’ in assignment
It takes me to this code
chin_::chin_(charon_ &handle) {
engine = handle;
}
engine is defined as
charon_* engine; and handle appears to be an address and should fall right into place, but it isn't. I think I am not using this correctly.
When you declare something like this :
chin_ engine_input;
chin_ needs a constructor with no parameters or you have to pass the parameters to it in the initializer list, otherwise you will get the error about no matching constructor.
What you can do is either have a default constructor that takes no params. Or make engine_input a pointer and create it with :
engine_input = new chin_(handle);
Alternatively you can pass handle to chin_ in the initializer list like this :
foo::foo(charon* handle):
chin_(handle)
{
}

I'm messing up my inheritance

So I've got a Piece class supposed to represent pieces on a board, from which I plan to have two other classes inheriting. I've gotten a lot of problems in doing so, however; here is the relevant code so far.
///
/// PIECE CLASS HERE
/// this is an abstract class from which Barrier and Pawn inherit.
class Piece
{
public:
Piece(Space* start);
sf::Shape m_Circle;
protected:
int m_X;
int m_Y;
int m_radius;
Space* CurrentSpace;
};
Piece::Piece(Space* start):
m_X(start->GetX()),
m_Y(start->GetY()),
m_radius(14),
CurrentSpace(start)
{}
///
/// BARRIER CLASS HERE
/// these are the white stones that block a player's path
class Barrier : public Piece
{
public:
Barrier(Space* initial);
void Move(Space* target, bool isCapturing);
};
Barrier::Barrier(Space* initial)
{
Piece(initial);
m_Circle = sf::Shape::Circle((float)m_X, (float)m_Y, (float)m_radius, sf::Color(255, 255, 255));
Move(initial);
}
void Barrier::Move(Space* target, bool isCapturing)
{
int xChange = abs(target->GetX() - m_X);
int yChange = abs(target->GetY() - m_Y);
m_Circle.Move((float)xChange, (float)yChange);
CurrentSpace.ToggleOccupied();
if(!isCapturing)
{
(*target).ToggleOccupied();
}
CurrentSpace = target;
}
I'm getting loads of errors I don't understand, in particular:
no matching function for call to Piece::Piece()
declaration of 'Piece initial' shadows a parameter
no matching function for call to 'Barrier::Move(Piece&)'
request for member 'ToggleOccupied' in '((Barrier*)this)->Barrier::<anonymous>.Piece::CurrentSpace', which is of non-class type 'Space*'|
Being new to C++, I don't understand what's going wrong with any of this. I tried to build my code analogous to the code I found in the book I used to learn C++, but apparently I've overlooked some subtlety. All the functions that I try to call seem to exist in the appropriate places, and I define them with the same values as in their prototype, I think.
The first error is caused by this:
Barrier::Barrier(Space* initial)
{
Piece(initial);
m_Circle = sf::Shape::Circle((float)m_X, (float)m_Y, (float)m_radius, sf::Color(255, 255, 255));
Move(initial);
}
Needs to look like:
Barrier::Barrier(Space* initial) : Piece(initial)
{
m_Circle = sf::Shape::Circle((float)m_X, (float)m_Y, (float)m_radius, sf::Color(255, 255, 255));
Move(initial);
}
The base class' constructor runs before your constructor (no matter what) -- you need to pass arguments to it if it requires arguments in the initialization list.
I'm not sure about the other errors because I don't know which lines they're occurring on.
The parenthesis in the line
Piece(initial);
are ignored by the compiler. You are declaring a variable with the same name as the parameter:
Piece initial;
To initialize the Piece base object with initial, you have to use the member initializer list:
Barrier::Barrier(Space* initial) : Piece(initial)
Also, the Move function expects two arguments, but you're only passing one. You forgot the boolean.
Good answers, all. Plus that final daunting line
request for member 'ToggleOccupied' in '((Barrier*)this)->Barrier::<anonymous>.Piece::CurrentSpace', which is of non-class type 'Space*'|
is being caused from
CurrentSpace.ToggleOccupied();
you have declared CurrentSpace to be a pointer, so this should be
CurrentSpace->ToggleOccupied();
If you want to initialize the super class, you should do it like this:
Barrier(Space* initial):
Piece(initial) {
...
}
If you don't explicitly initialize the base type, the compiler will try to initialize it by calling a constructor with an empty argument list, like this:
Barrier(Space* initial):
Piece() {
...
}
But since you don't define a constructor for Piece that takes zero arguments, you get the compiler error you described.