I have a class with two constructors, one that takes no arguments and one that takes one argument.
Creating objects using the constructor that takes one argument works as expected. However, if I create objects using the constructor that takes no arguments, I get an error.
For instance, if I compile this code (using g++ 4.0.1)…
class Foo
{
public:
Foo() {};
Foo(int a) {};
void bar() {};
};
int main()
{
// this works...
Foo foo1(1);
foo1.bar();
// this does not...
Foo foo2();
foo2.bar();
return 0;
}
… I get the following error:
nonclass.cpp: In function ‘int main(int, const char**)’:
nonclass.cpp:17: error: request for member ‘bar’ in ‘foo2’, which is of non-class type ‘Foo ()()’
Why is this, and how do I make it work?
user2864740
59.6k15 gold badges142 silver badges215 bronze badges
asked May 18, 2009 at 12:38
1
Foo foo2();
change to
Foo foo2;
You get the error because compiler thinks of
Foo foo2()
as of function declaration with name ‘foo2’ and the return type ‘Foo’.
But in that case If we change to Foo foo2
, the compiler might show the error " call of overloaded ‘Foo()’ is ambiguous"
.
answered May 18, 2009 at 12:41
Mykola GolubyevMykola Golubyev
57.7k15 gold badges89 silver badges102 bronze badges
5
Just for the record..
It is actually not a solution to your code, but I had the same error message when incorrectly accessing the method of a class instance pointed to by myPointerToClass
, e.g.
MyClass* myPointerToClass = new MyClass();
myPointerToClass.aMethodOfThatClass();
where
myPointerToClass->aMethodOfThatClass();
would obviously be correct.
answered Mar 5, 2013 at 9:30
ezdazuzenaezdazuzena
6,0706 gold badges41 silver badges69 bronze badges
0
Parenthesis is not required to instantiate a class object when you don’t intend to use a parameterised constructor.
Just use Foo foo2;
It will work.
answered Aug 1, 2017 at 6:43
Reena CyrilReena Cyril
3974 silver badges11 bronze badges
Adding to the knowledge base, I got the same error for
if(class_iter->num == *int_iter)
Even though the IDE gave me the correct members for class_iter. Obviously, the problem is that "anything"::iterator
doesn’t have a member called num
so I need to dereference it. Which doesn’t work like this:
if(*class_iter->num == *int_iter)
…apparently. I eventually solved it with this:
if((*class_iter)->num == *int_iter)
I hope this helps someone who runs across this question the way I did.
answered Feb 11, 2014 at 21:56
MattMatt
7757 silver badges23 bronze badges
0
I was having a similar error, it seems that the compiler misunderstand the call to the constructor without arguments. I made it work by removing the parenthesis from the variable declaration, in your code something like this:
class Foo
{
public:
Foo() {};
Foo(int a) {};
void bar() {};
};
int main()
{
// this works...
Foo foo1(1);
foo1.bar();
// this does not...
Foo foo2; // Without "()"
foo2.bar();
return 0;
}
answered Mar 9, 2015 at 16:18
3
I ran into a case where I got that error message and had
Foo foo(Bar());
and was basically trying to pass in a temporary Bar object to the Foo constructor. Turns out the compiler was translating this to
Foo foo(Bar(*)());
that is, a function declaration whose name is foo that returns a Foo that takes in an argument — a function pointer returning a Bar with 0 arguments. When passing in temporaries like this, better to use Bar{}
instead of Bar()
to eliminate ambiguity.
answered Sep 7, 2017 at 11:01
solstice333solstice333
3,3411 gold badge30 silver badges28 bronze badges
If you want to declare a new substance with no parameter (knowing that the object have default parameters) don’t write
type substance1();
but
type substance;
Prashant_M
2,8581 gold badge30 silver badges24 bronze badges
answered Feb 8, 2018 at 16:49
Certainly a corner case for this error, but I received it in a different situation, when attempting to overload the assignment operator=
. It was a bit cryptic IMO (from g++ 8.1.1).
#include <cstdint>
enum DataType
{
DT_INT32,
DT_FLOAT
};
struct PrimitiveData
{
union MyData
{
int32_t i;
float f;
} data;
enum DataType dt;
template<typename T>
void operator=(T data)
{
switch(dt)
{
case DT_INT32:
{
data.i = data;
break;
}
case DT_FLOAT:
{
data.f = data;
break;
}
default:
{
break;
}
}
}
};
int main()
{
struct PrimitiveData pd;
pd.dt = DT_FLOAT;
pd = 3.4f;
return 0;
}
I received 2 «identical» errors
error: request for member ‘i’ [and 'f'] in ‘data’, which is of non-class type ‘float’
(The equivalent error for clang
is:
error: member reference base type 'float' is not a structure or union
)
for the lines data.i = data;
and data.f = data;
. Turns out the compiler was confusing local variable name ‘data’ and my member variable data
. When I changed this to void operator=(T newData)
and data.i = newData;
, data.f = newData;
, the error went away.
answered Aug 11, 2018 at 21:58
yanoyano
4,7872 gold badges23 silver badges35 bronze badges
@MykolaGolubyev has already given wonderful explanation. I was looking for a solution to do somthing like this MyClass obj ( MyAnotherClass() )
but the compiler was interpreting it as a function declaration.
C++11 has braced-init-list. Using this we can do something like this
Temp t{String()};
However, this:
Temp t(String());
throws compilation error as it considers t
as of type Temp(String (*)())
.
#include <iostream>
class String {
public:
String(const char* str): ptr(str)
{
std::cout << "Constructor: " << str << std::endl;
}
String(void): ptr(nullptr)
{
std::cout << "Constructor" << std::endl;
}
virtual ~String(void)
{
std::cout << "Destructor" << std::endl;
}
private:
const char *ptr;
};
class Temp {
public:
Temp(String in): str(in)
{
std::cout << "Temp Constructor" << std::endl;
}
Temp(): str(String("hello"))
{
std::cout << "Temp Constructor: 2" << std::endl;
}
virtual ~Temp(void)
{
std::cout << "Temp Destructor" << std::endl;
}
virtual String get_str()
{
return str;
}
private:
String str;
};
int main(void)
{
Temp t{String()}; // Compiles Success!
// Temp t(String()); // Doesn't compile. Considers "t" as of type: Temp(String (*)())
t.get_str(); // dummy statement just to check if we are able to access the member
return 0;
}
answered May 5, 2020 at 18:05
abhiaroraabhiarora
9,6135 gold badges31 silver badges55 bronze badges
i got this error and i am not able to solve by myself
source.cpp:85:8: error: request for member ‘put_tag’ in ‘aux’, which is of non-class type ‘Keyword()’
source.cpp:86:8: error: request for member ‘put_site’ in ‘aux’, which is of non-class type ‘Keyword()’
make: *** [source.o] Error 1
the code which gives me this error is
Keyword aux();
aux.put_tag(word);
aux.put_site(site);
I must mention that word and site are char *
type
Now, my Keyword class definition is this one:
class Keyword{
private:
std::string tag;
Stack<std::string> weblist;
public:
Keyword();
~Keyword();
void put_tag(std::string word)
{
tag = word;
}
void put_site(std::string site)
{
weblist.push(site);
}
};
Thank you very much!
Update
By modifying
Keyword aux();
aux.put_tag(word);
aux.put_site(site);
in
Keyword aux;
aux.put_tag(word);
aux.put_site(site);
i got this error:
source.o: In function `Algorithm::indexSite(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)':
source.cpp:(.text+0x2c6): undefined reference to `Keyword::Keyword()'
source.cpp:(.text+0x369): undefined reference to `Keyword::~Keyword()'
source.cpp:(.text+0x4a8): undefined reference to `Keyword::~Keyword()'
source.o: In function `Keyword::put_site(std::basic_string<char, std::char_traits<char>, std::allocator<char> >)':
source.cpp:(.text._ZN7Keyword8put_siteESs[Keyword::put_site(std::basic_string<char, std::char_traits<char>, std::allocator<char> >)]+0x2a): undefined reference to `Stack<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >::push(std::basic_string<char, std::char_traits<char>, std::allocator<char> >)'
collect2: ld returned 1 exit status
make: *** [tema3] Error 1
Your current problem is that the USB Serial interface of the Leonardo isn’t a hardware serial device, it’s a CDC/ACM device, and the class for that isn’t HardwareSerial, it’s Serial_.
So you can’t pass it to a function that expects a HardwareSerial.
What you should be using, instead, is the Stream class. That will allow you to pass any object that is based on the Stream class, such as HardwareSerial, Serial_, Client, etc. Many different things, including serial and networking protocols, use Stream as their base class.
It does have the down side, though, that you have to initialize the Stream objects in your sketch (that is, do the Serial.begin(…) and Serial1.begin(…) in your sketch not your class) because the Stream class doesn’t have the concept of a baud rate, and so no begin(baud) function.
This is what I mean:
class Esp8266 {
public:
Esp8266();
void begin(Stream &wifiCom, Stream &debugCom);
private:
Stream *_wifiCom;
Stream *_debugCom;
};
Esp8266::Esp8266() {
}
void Esp8266::begin(Stream &wifiCom, Stream &debugCom) {
_wifiCom = &wifiCom;
_debugCom = &debugCom;
while (!_debugCom) {
;
}
}
Esp8266 esp;
void setup() {
Serial.begin(115200);
Serial1.begin(115200);
esp.begin(Serial, Serial1);
} // end of setup
void loop() {
} // end of
Note, as well, my use of pass-by-reference (Stream &whatever) so you don’t have to pass a pointer in your begin function. Also notice the use of unique variable names in the class (I always prefix my member variables with _
) so you don’t have to keep putting this->
in everywhere.
To be able to move the .begin()
function inside your class you will have to use both HardwareSerial
and Serial_
object types within your class. There’s two ways this may be done.
First is dynamic casting:
void Esp8266::begin(Stream &wifiCom, Stream *debugCom) {
_wifiCom = &wifiCom;
_debugCom = &debugCom;
HardwareSerial *hard;
Serial_ *cdc;
if (hard = dynamic_cast<HardwareSerial*>(_wifiCom)) {
hard->begin(115200);
} else if (cdc = dynamic_cast<Serial_*>(_wifiCom)) {
cdc->begin(115200);
}
if (hard = dynamic_cast<HardwareSerial*>(_debugCom)) {
hard->begin(115200);
} else if (cdc = dynamic_cast<Serial_*>(_debugCom)) {
cdc->begin(115200);
}
}
I haven’t tested this, and I don’t know if the Arduino’s cut-down C++ library is even capable of it, but it’s worth a try.
The other method is to overload the .begin()
function of your class with multiple versions that take different parameters:
void Esp8266::begin(Serial_ &wifiCom, HardwareSerial *debugCom) {
_wifiCom = &wifiCom;
_debugCom = &debugCom;
wifiCom.begin(115200);
debugCom.begin(115200);
}
void Esp8266::begin(HardwareSerial &wifiCom, HardwareSerial *debugCom) {
_wifiCom = &wifiCom;
_debugCom = &debugCom;
wifiCom.begin(115200);
debugCom.begin(115200);
}
void Esp8266::begin(HardwareSerial &wifiCom, Serial_ *debugCom) {
_wifiCom = &wifiCom;
_debugCom = &debugCom;
wifiCom.begin(115200);
debugCom.begin(115200);
}
You’re still storing them internally as Stream
objects in all cases, but within the begin()
function itself you also have them available as their child classes. It does mean you have duplicate code copied between the different versions of begin()
. You could modularize it a little more though by moving the duplicated code into functions which would only need to be duplicated twice, not three times — one to act on a single Serial_
object and one to act on a single HardwareSerial
object:
void Esp8266::initSerial(Serial_ *ser) {
ser->begin(115200);
}
void Esp8266::initSerial(HardwareSerial *ser) {
ser->begin(115200);
}
void Esp8266::begin(Serial_ &wifiCom, HardwareSerial *debugCom) {
_wifiCom = &wifiCom;
_debugCom = &debugCom;
initSerial(&wifiCom);
initSerial(&debugCom);
}
... etc x3 ...
- Forum
- General C++ Programming
- request for member of non class type?
request for member of non class type?
When I run my code I get this error and I don’t know how to fix it.
error: request for member ‘push_back’ in ‘v’, which is of non-class type ‘Vector<int>()’|
Here’s my updated code.
Vector.h
|
|
Vector.cpp
|
|
main.cpp
|
|
Last edited on
Vector<int> v();
Declares a function taking no arguments and returning Vector<int>
.
You probably meant Vector<int> v;
. This line return an error because you do not have a default constructor for your class.
Last edited on
I thought this was my default constructor.
That is declaration. Where is it defined?
The error is on line 69. The parameter requires const: push_back(const T &x)
You have several more errors in resize(…).
On line 48: missing *
On line 49: Remove buffer.
Line 55 and the loop on line 57 don’t make sense. Replace it with buffer = newBuffer;
Last edited on
Thanks coder that makes more sense. I still don’t understand my error for using this.
Here’s my updated code.
Vector.h
|
|
Vector.cpp
|
|
main.cpp
|
|
Last edited on
Thanks coder that makes more sense. I still don’t understand my error for using this.
Is there still an error? The line itself is ok.
Topic archived. No new replies allowed.
I have a class with two constructors, one that takes no arguments and one that takes one argument.
Creating objects using the constructor that takes one argument works as expected. However, if I create objects using the constructor that takes no arguments, I get an error.
For instance, if I compile this code (using g++ 4.0.1)…
class Foo
{
public:
Foo() {};
Foo(int a) {};
void bar() {};
};
int main()
{
// this works...
Foo foo1(1);
foo1.bar();
// this does not...
Foo foo2();
foo2.bar();
return 0;
}
… I get the following error:
nonclass.cpp: In function ‘int main(int, const char**)’:
nonclass.cpp:17: error: request for member ‘bar’ in ‘foo2’, which is of non-class type ‘Foo ()()’
Why is this, and how do I make it work?