Log in

View Full Version : What does the ampersand (&) mean in errors?


JPruim
10-11-2012, 21:07
I get the error stack as follows when trying to compile the following code:


C:/Users/Josh/WindRiver/workspace/SimpleTemplate/limitSwitch.cpp: In constructor `limitSwitch::limitSwitch(UINT32)':
C:/Users/Josh/WindRiver/workspace/SimpleTemplate/limitSwitch.cpp:8: error: no matching function for call to `DigitalInput::DigitalInput()'
C:/WindRiver/vxworks-6.3/target/h/WPILib/DigitalInput.h:21: note: candidates are: DigitalInput::DigitalInput(const DigitalInput&)
C:/WindRiver/vxworks-6.3/target/h/WPILib/DigitalInput.h:24: note: DigitalInput::DigitalInput(UINT8, UINT32)
C:/WindRiver/vxworks-6.3/target/h/WPILib/DigitalInput.h:23: note: DigitalInput::DigitalInput(UINT32)
C:/Users/Josh/WindRiver/workspace/SimpleTemplate/limitSwitch.cpp:9: error: no match for call to `(DigitalInput) (UINT32&)'
C:\WindRiver\vxworks-6.3\host\x86-win32\bin\make.exe: *** [SimpleTemplate_partialImage/Debug/Objects/SimpleTemplate/limitSwitch.o] Error 1
Build Failed in Project 'SimpleTemplate' (Process Exit Value was 2): 2012-11-10 18:06:08 (Elapsed Time: 00:02)


when compiling


#include "WPILib.h"

class limitSwitch
{
DigitalInput di; // robot drive system

public:
limitSwitch(UINT32 p){
di(p);
}
};


Why is there an & symbol after UINT32? in the 'No match for call to...' error?

phynix
11-11-2012, 17:58
You have a problem in how you're initializing the variable di. In C++, you an only initialize variables and objects once--generally at the start of the constructor. You have the general idea right, but not the implementation. Try this instead:


#include "WPILib.h"

class limitSwitch
{
DigitalInput di; // robot drive system

public:
limitSwitch(UINT32 p) : di(p){
//look at above line ^^
}
};


Regarding the ampersand (&).

This is C++ syntax--not something specific to error messages.

When you declare a function (or constructor, for that matter), you have a couple of options in how you want to handle input parameters.


void increment(int& i){
i++;
}


^^This code will increment an integer. the &, in this case, means you're passing the value by reference. Whatever you do to this value will occur to the actual variable in whatever code you use.

Likewise, every class has a default copy constructor--whether or not it is declared. In the case of the DigitalInput class, the copy constructor is defined [by the compiler] as:


DigitalInput::DigitalInput(const DigitalInput& somevalue)


Of course, the variable name (somevalue, as I put), doesn't matter--so the compiler doesn't print it out.

The copy constructor creates a copy of the input DigitalInput.

So, that's all the ampersand is doing in this case.

In the second part, no match for call to `(DigitalInput) (UINT32&)'

I'm not exactly sure what's going on--but what you're trying to do _is_ illegal. You can't initialize a variable like that.

Based on what I'm seeing, it looks like 1) it's trying to cast the integer to a DigitalInput (which is completed through the use of a compiler-defined copy constructor), or 2) it's trying to call a copy constructor on DigitalInput itself, trying to pass the integer as a value.


On a side note....

Using C++ is is also possible to make a class be able to be cast to another class or variable, using the 'operator' functions.

For example, in a class, you could define a 'function' as:


class MyClass{
public:
int value;
operator double(double input){
value=double;
}
};


What you can then do is say MyClass c = 42.4. And it will set 'value' to 42.4.

In this case, no such operator is defined in DigitalInput..and, so, it doesn't know what to do.

Greg McCoy
12-11-2012, 12:32
Initialization in C++ is a little tricky when you're using objects as member variables.

When you declare the limitSwitch(UINT32) constructor, the compiler is trying to use the default constructor (http://en.wikipedia.org/wiki/Default_constructor) to create the di object, before it even looks at your constructor body. The DigitalInput class doesn't have a default (or zero-argument) constructor, so the compiler is giving you a list of the constructors which are available. You can tell the compiler to use another constructor by using an "initialization list."

I think what you mean to do is this:


#include "WPILib.h"

class limitSwitch
{
DigitalInput di; // robot drive system

public:
limitSwitch(UINT32 p) : di (p) { }
};



Hope this helps! Here are some links for more information:

Initialization Lists in C++ (http://www.cprogramming.com/tutorial/initialization-lists-c++.html)
Constructor initialization lists (http://www.learncpp.com/cpp-tutorial/101-constructor-initialization-lists/)

Greg McCoy
12-11-2012, 14:48
I just saw your other thread (http://www.chiefdelphi.com/forums/showthread.php?t=109471) - there are a lot of subtle differences between C++ and Java, and the ampersand is one of them. In your Java class...

// LimitSwitch.java
public class LimitSwitch {

protected DigitalInput di;

public LimitSwitch(int portNumber) {
di = new DigitalInput(portNumber);
}

public boolean isOpen(){
if (di.get() == true) {
return true;
} else return false;
}

public boolean isClosed(){
return (!isOpen());
}
}


...di is not a DigitalInput, it's actually a reference to a DigitalInput.

Unlike Java, in C++ object variables hold value types. In C++ there are references (http://en.wikipedia.org/wiki/Reference_(C%2B%2B)), which are sort of the equivalent to what you are used to in Java. The ampersand you're seeing indicates this reference type. For example, the const DigitalInput & in the DigitalInput constructor prototype means you should pass a reference to a DigitalInput object; not an actual DigitalInput object instance variable. This is conceptually similar to C-style pointers (which are also available in C++).

Here's how you might translate your Java class using a pointer to match the Java semantics:

// C++
#include "WPILib.h"

class LimitSwitch
{
DigitalInput *di;

public:
LimitSwitch(UINT32 p) // constructor
{
di = new DigitalInput(p);
}

~LimitSwitch() // destructor
{
delete di;
}

bool GetState()
{
return di->Get();
}
};


There are a lot of other differences between C++ and Java; I'd recommend looking at the following resources:

Moving from Java to C++ (http://www.horstmann.com/ccj2/ccjapp3.html)
Comparison of Java and C++ (http://en.wikipedia.org/wiki/Comparison_of_Java_and_C%2B%2B) - Wikipedia
The C++ Programming Language (http://amzn.com/0201889544) - book by the designer of the language


Again, hope this helps :]