Request for member which is of non class type c ошибка

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's user avatar

user2864740

59.6k15 gold badges142 silver badges215 bronze badges

asked May 18, 2009 at 12:38

sarnesjo's user avatar

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".

lost_in_the_source's user avatar

answered May 18, 2009 at 12:41

Mykola Golubyev's user avatar

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.

metamorphosis's user avatar

answered Mar 5, 2013 at 9:30

ezdazuzena's user avatar

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 Cyril's user avatar

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

Matt's user avatar

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

Alexis Lopez Zubieta's user avatar

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

solstice333's user avatar

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's user avatar

Prashant_M

2,8581 gold badge30 silver badges24 bronze badges

answered Feb 8, 2018 at 16:49

Mohcine el's user avatar

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

yano's user avatar

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

abhiarora's user avatar

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#ifndef VECTOR_H_INCLUDED
#define VECTOR_H_INCLUDED

template <class T>
class Vector
{
private:
   unsigned int my_size;
   unsigned int my_capacity;
   T * buffer;

public:

   //Vector;
   Vector();
   void push_back(const T & x);
   int resize(int size);
};

#endif // VECTOR_H_INCLUDED 

Vector.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <iostream>
#include "Vector.h"

using namespace std;

template <class T>
Vector<T>::Vector()
{
	my_size = 0;
	my_capacity = 0;
	buffer = nullptr;
}

template <class T>
void Vector<T>::push_back(const T &x)
{
    if(my_size == my_capacity)
    {
        resize(my_capacity+5);
    }
    buffer[my_size] = x;
    my_size++;
}

template <class T>
int Vector<T>::resize(int size)
{
    if(buffer == nullptr)
    {
        buffer = new T[size];
        my_capacity = size;
    }
    else{
        T * newBuffer = new T[size];
        for(int i = 0; i < my_size; i++)
        {
            newBuffer[i] = buffer[i];
        }

        delete [] buffer;
        buffer = newBuffer;
    }
}

main.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
#include <string>
#include <cassert>
#include "Vector.h"

using namespace std;

int main()
{

   Vector<int> v;
   //v.push_back(8);
}

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#ifndef VECTOR_H_INCLUDED
#define VECTOR_H_INCLUDED

template <class T>
class Vector
{
private:
   unsigned int my_size;
   unsigned int my_capacity;
   T * buffer;

public:

   //Vector;
   Vector();
   void push_back(const T & x);
   int resize(int size);
};

#endif // VECTOR_H_INCLUDED 

Vector.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <iostream>
#include "Vector.h"

using namespace std;

template <class T>
Vector<T>::Vector()
{
	my_size = 0;
	my_capacity = 0;
	buffer = nullptr;
}

template <class T>
void Vector<T>::push_back(const T &x)
{
    if(my_size == my_capacity)
    {
        resize(my_capacity+5);
    }
    buffer[my_size] = x;
    my_size++;
}

template <class T>
int Vector<T>::resize(int size)
{
    if(buffer == nullptr)
    {
        buffer = new T[size];
        my_capacity = size;
    }
    else{
        T * newBuffer = new T[size];
        for(int i = 0; i < my_size; i++)
        {
            newBuffer[i] = buffer[i];
        }

        delete [] buffer;
        buffer = newBuffer;
    }
}

main.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
#include <string>
#include <cassert>
#include "Vector.h"

using namespace std;

int main()
{

   Vector<int> v;
   //v.push_back(8);
}

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?

  • Report keydisk ru 465 неизвестная ошибка smtp error code 3
  • Report json 1c ошибка
  • Report builder код ошибки
  • Replace toner cartridge brother ошибка
  • Replace card battery рено меган 2 как убрать ошибку