Implementing function outside struct

I have this code where I have declared a struct with some functions. Trying to write the function implementation outside the struct declaration and do not know how to proceed.

#ifndef ParseEl_hh
#define ParseEl_hh

#include <iostream>
#include <fstream>

#include "DynBaseObj.hh"
#include "List.hh"
#include "Stack.hh"
#include "Tree.hh"
#include "Vect2.hh"
#include "Vector.hh"
#include "String.hh"
#include "common.hh"

enum TypeParse { PARAM, LIST };

////////////////////////////////////////////////////////////////////////////////////////////////////

struct ParseEl {

  enum TypeParse Type;
  int  Hash;
  String  Str;
  String  Name;
  List<String>  StringList;
  List<int>  Ord;

  ParseEl() { }

  ParseEl(
    const String&  name,
    String&  s,
    const List<int>&  ord) {

    Name = name;
    Str = s;
    Type = PARAM;
    Ord = ord;
    Hash = Name.Hash();

    while ((Ord.size() > 0) && (Ord[Ord.size()-1] == 0)) {
        Ord.Delete(Ord.size() - 1);
    }

  }

////////////////////////////////////////////////////////////////////////////////////////////////////

  ParseEl(
    const String&  name,
    const List<String>&  ls,
    const List<int>&  ord) {

    Name = name;
    StringList = ls;
    Type = LIST;
    Ord = ord;
    Hash = Name.Hash();

    while ((Ord.size() > 0) && (Ord[Ord.size()-1] == 0)) {
      Ord.Delete(Ord.size() - 1);
    }

  }

  ParseEl(const ParseEl&  parsel ) {

    Name = parsel.Name;
    Type = parsel.Type;
    Str = parsel.Str;
    StringList = parsel.StringList;
    Ord = parsel.Ord;
    Hash = parsel.Hash;

  }

  friend  int  operator == (
      const ParseEl  p1,
      const ParseEl  p2) {

      return (    (p1.Hash == p2.Hash) && (p1.Type == p2.Type)
          && (p1.Name == p2.Name)  && (p1.Ord == p2.Ord)
          && (p1.Str == p2.Str) && (p1.StringList == p2.StringList) );

  }

};

#endif

---------- Post updated at 09:08 AM ---------- Previous update was at 06:46 AM ----------

I have now changed the code and things are working fine. My last problem is how to take care of ParseEl() { } to be outside the struct. It is not doing anything so I suppose I can just declare it inside the struct as ParseEl();

#ifndef ParseEl_hh
#define ParseEl_hh

#include <iostream>
#include <fstream>

#include "DynBaseObj.hh"
#include "List.hh"
#include "Stack.hh"
#include "Tree.hh"
#include "Vect2.hh"
#include "Vector.hh"
#include "String.hh"
#include "common.hh"

enum TypeParse { PARAM, LIST };

////////////////////////////////////////////////////////////////////////////////////////////////////

struct ParseEl {

// -- Attributes -----------------------------------------------------------------------------------

  enum TypeParse Type;
  int  Hash;
  String  Str;
  String  Name;
  List<String>  StringList;
  List<int>  Ord;

// -- Operations -----------------------------------------------------------------------------------

  ParseEl() { }

  ParseEl(
    const String&  name,
    String&  s,
    const List<int>&  ord);

  ParseEl(
    const String&  name,
    const List<String>&  ls,
    const List<int>&  ord);

  ParseEl(
    const ParseEl&  parsel);

  friend int operator  == (
    const ParseEl  p1,
    const ParseEl  p2);

};

////////////////////////////////////////////////////////////////////////////////////////////////////

  ParseEl::ParseEl(
    const String&  name,
    String&  s,
    const List<int>&  ord) {

    Name = name;
    Str = s;
    Type = PARAM;
    Ord = ord;
    Hash = Name.Hash();

    while ((Ord.size() > 0) && (Ord[Ord.size()-1] == 0)) {
        Ord.Delete(Ord.size() - 1);
    }

  }

////////////////////////////////////////////////////////////////////////////////////////////////////

  ParseEl::ParseEl(
    const String&  name,
    const List<String>&  ls,
    const List<int>&  ord) {

    Name = name;
    StringList = ls;
    Type = LIST;
    Ord = ord;
    Hash = Name.Hash();

    while ((Ord.size() > 0) && (Ord[Ord.size()-1] == 0)) {
      Ord.Delete(Ord.size() - 1);
    }

  }

////////////////////////////////////////////////////////////////////////////////////////////////////

  ParseEl::ParseEl(
    const ParseEl&  parsel) {

    Name = parsel.Name;
    Type = parsel.Type;
    Str = parsel.Str;
    StringList = parsel.StringList;
    Ord = parsel.Ord;
    Hash = parsel.Hash;

  }

////////////////////////////////////////////////////////////////////////////////////////////////////

  int  operator == (
    const ParseEl  p1,
    const ParseEl  p2) {

    return (    (p1.Hash == p2.Hash) && (p1.Type == p2.Type) && (p1.Name == p2.Name)
             && (p1.Ord == p2.Ord) && (p1.Str == p2.Str) && (p1.StringList == p2.StringList) );

  }

#endif

What you want: function pointers. Create a function pointer as an element of the struct.

The Function Pointer Tutorials - Index

Currently ParseEl is being used by class Parsing and called as follows:

Parsing.hh:#include "ParseEl.hh"
Parsing.hh:  List<ParseEl>  Index;                //
Parsing.hh:              Index += ParseEl(CompleteName, Ends, Ord);
Parsing.hh:              Index += ParseEl(CompleteName, L, Ord);
Parsing.hh:          Index += ParseEl(Name, Ends, Ord);

Also I use it as a private member in class Parsing as follows:

List<ParseEl>  Index; 

And in its own class such as

const ParseEl  p1

Currently I just want the same functionality, basically leaving
everything as it is, however do the declarations inside the class
definition and all implementations outside.

None of your implementations are inside the structure anymore, which will allow you to remove them from the header file and put them in a separate source file. Compile and link this source file in with the rest of your project, and the symbols should be found.

#ifndef ParseEl_hh
#define ParseEl_hh

#include <iostream>
#include <fstream>

#include "DynBaseObj.hh"
#include "List.hh"
#include "Stack.hh"
#include "Tree.hh"
#include "Vect2.hh"
#include "Vector.hh"
#include "String.hh"
#include "common.hh"

enum TypeParse { PARAM, LIST };

////////////////////////////////////////////////////////////////////////////////////////////////////

struct ParseEl {

// -- Attributes -----------------------------------------------------------------------------------

  enum TypeParse Type;
  int  Hash;
  String  Str;
  String  Name;
  List<String>  StringList;
  List<int>  Ord;

// -- Operations -----------------------------------------------------------------------------------

  ParseEl() { }

  ParseEl(
    const String&  name,
    String&  s,
    const List<int>&  ord);

  ParseEl(
    const String&  name,
    const List<String>&  ls,
    const List<int>&  ord);

  ParseEl(
    const ParseEl&  parsel);

  friend int operator  == (
    const ParseEl  p1,
    const ParseEl  p2);

};

#endif
//parseel.cpp

#include "parseel.h"

////////////////////////////////////////////////////////////////////////////////////////////////////

  ParseEl::ParseEl(
    const String&  name,
    String&  s,
    const List<int>&  ord) {

    Name = name;
    Str = s;
    Type = PARAM;
    Ord = ord;
    Hash = Name.Hash();

    while ((Ord.size() > 0) && (Ord[Ord.size()-1] == 0)) {
        Ord.Delete(Ord.size() - 1);
    }

  }

////////////////////////////////////////////////////////////////////////////////////////////////////

  ParseEl::ParseEl(
    const String&  name,
    const List<String>&  ls,
    const List<int>&  ord) {

    Name = name;
    StringList = ls;
    Type = LIST;
    Ord = ord;
    Hash = Name.Hash();

    while ((Ord.size() > 0) && (Ord[Ord.size()-1] == 0)) {
      Ord.Delete(Ord.size() - 1);
    }

  }

////////////////////////////////////////////////////////////////////////////////////////////////////

  ParseEl::ParseEl(
    const ParseEl&  parsel) {

    Name = parsel.Name;
    Type = parsel.Type;
    Str = parsel.Str;
    StringList = parsel.StringList;
    Ord = parsel.Ord;
    Hash = parsel.Hash;

  }

////////////////////////////////////////////////////////////////////////////////////////////////////

  int  operator == (
    const ParseEl  p1,
    const ParseEl  p2) {

    return (    (p1.Hash == p2.Hash) && (p1.Type == p2.Type) && (p1.Name == p2.Name)
             && (p1.Ord == p2.Ord) && (p1.Str == p2.Str) && (p1.StringList == p2.StringList) );

  }

---------- Post updated at 11:06 AM ---------- Previous update was at 11:04 AM ----------

Also, you really should make your comparison operator pass by reference! Duplicating two lists whenever you want to just compare them will not be efficient!

  friend int operator  == (
    const ParseEl  &p1,
    const ParseEl  &p2);
  int  operator == (
    const ParseEl  &p1,
    const ParseEl  &p2) {

    return (    (p1.Hash == p2.Hash) && (p1.Type == p2.Type) && (p1.Name == p2.Name)
             && (p1.Ord == p2.Ord) && (p1.Str == p2.Str) && (p1.StringList == p2.StringList) );

  }

That's correct. My question is what shall I do about

 ParseEl() { }

You could either inline it:

...

inline ParseEl() { }

...

Or do the same thing with it you did with everything else:

ParseEl();
ParseEl::ParseEl() { }

You should put something in your constructor anyway. You're leaving your Type and Hash variables unset, hence at values which only might, usually be zero...

1 Like

I was thinking of letting the compiler take care of the constructor, thus removing the line. Any opinion about this?

I don't think it will take care of it, I think it will omit it entirely.

But since this is a struct, it may not in technicality need a constructor, either.

But you still ought to have one I think, for the reasons mentioned earlier. You're leaving values undefined, which can have unpredictable and undesirable effects. It may work in most circumstances but break mysteriously in others.