web-dev-qa-db-fra.com

erreur: demande du membre '..' dans '..' qui est de type non classe

J'ai une classe avec deux constructeurs, un qui ne prend aucun argument et un qui prend un argument.

La création d'objets à l'aide du constructeur prenant un argument fonctionne comme prévu. Cependant, si je crée des objets à l'aide du constructeur qui ne prend aucun argument, j'obtiens une erreur.

Par exemple, si je compile ce code (avec 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;
}

... j'obtiens l'erreur suivante:

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 ()()’

Pourquoi est-ce cela et comment puis-je le faire fonctionner?

373
sarnesjo
Foo foo2();

changer à

Foo foo2;

Vous obtenez l'erreur parce que le compilateur pense à

Foo foo2()

en tant que déclaration de fonction avec le nom 'foo2' et le type de retour 'Foo'.

Mais dans ce cas, si nous passons à Foo foo2, le compilateur pourrait afficher l'erreur " call of overloaded ‘Foo()’ is ambiguous".

562
Mykola Golubyev

Juste pour info..

En réalité, ce n'est pas une solution à votre code, mais j'avais le même message d'erreur lorsque j'accédais de manière incorrecte à la méthode d'une instance de classe indiquée par myPointerToClass, par exemple.

MyClass* myPointerToClass = new MyClass();
myPointerToClass.aMethodOfThatClass();

myPointerToClass->aMethodOfThatClass();

serait évidemment correct.

37
ezdazuzena

En ajoutant à la base de connaissances, j'ai eu la même erreur pour 

if(class_iter->num == *int_iter)

Même si IDE m'a fourni les bons membres pour class_iter. De toute évidence, le problème est que "anything"::iterator n'a pas de membre appelé num et que je dois donc le déréférencer. Ce qui ne fonctionne pas comme ça:

if(*class_iter->num == *int_iter)

...Apparemment. Je l'ai finalement résolu avec ceci:

if((*class_iter)->num == *int_iter)

J'espère que cela aidera quelqu'un qui rencontre cette question comme je l'ai fait.

9
Matt

J'avais une erreur similaire, il semble que le compilateur comprenne mal l'appel au constructeur sans arguments. Je l'ai fait fonctionner en supprimant la parenthèse de la déclaration de variable, dans votre code quelque chose comme ça:

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;
}
4

La parenthèse n'est pas nécessaire pour instancier un objet de classe lorsque vous ne prévoyez pas d'utiliser un constructeur paramétré.

Il suffit d'utiliser Foo Foo2;

Ça va marcher.

4
Reena Cyril

J'ai rencontré un cas où j'ai reçu ce message d'erreur et

Foo foo(Bar());

et essayait essentiellement de passer un objet Bar temporaire au constructeur Foo. Il s'avère que le compilateur traduisait ceci en

Foo foo(Bar(*)());

c'est-à-dire une déclaration de fonction dont le nom est foo et qui retourne un Foo prenant un argument - un pointeur de fonction renvoyant une barre avec 0 argument. Lorsque vous passez dans des temporaires comme celui-ci, il vaut mieux utiliser Bar{} au lieu de Bar() pour éliminer les ambiguïtés.

1
solstice333

Si vous souhaitez déclarer une nouvelle substance sans paramètre (sachant que l'objet a des paramètres par défaut), n'écrivez pas. 

 type substance1();

mais

 type substance;
0
Mo el

Certainement un cas de coin pour cette erreur, mais je l’ai reçue dans une situation différente lorsque je tentais de surcharger l’affectation operator= C'était un peu cryptique IMO (à partir de 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;
}

J'ai reçu 2 erreurs "identiques"

error: request for member ‘i’ [and 'f'] in ‘data’, which is of non-class type ‘float’

(L'erreur équivalente pour clang est: error: member reference base type 'float' is not a structure or union)

pour les lignes data.i = data; et data.f = data;. Le compilateur confondait le nom de la variable locale 'data' et ma variable membre data. Quand j'ai changé ceci en void operator=(T newData) et data.i = newData;, data.f = newData;, l'erreur est partie.

0
yano