1

This linker error is in the main.cpp and is in the foreach.h class. Both the constructor and deconstructor is tagged as an error.

LNK2019: unresolved external symbol

"public: __thiscall FE_Iterator::~FE_Iterator(void)" referenced in function "public: __thiscall Set,class std::allocator > >::Iterator::~Iterator(void)"

"public: __thiscall FE_Iterator::FE_Iterator(void)" referenced in function "private: __thiscall Set,class std::allocator > >::Iterator::Iterator(class Set,class std::allocator > > *)"

foreach.h

/*
 * File: foreach.h
 * Last modified on Thu Jun 11 12:04:09 2009 by eroberts
 * -----------------------------------------------------
 * This interface defines the foreach keyword, which is used to
 * simplify iteration.  All iterable classes import this interface,
 * so clients never need to do so explicitly.
 */

#ifndef _foreach_h
#define _foreach_h

#include "genlib.h"

/* These #includes are for files that contain "in" as a token */

#include <ios>
#include <fstream>
#include <sstream>

/* Redefine the ios constants (one of which is "in") */

static const ios::openmode IOS_APP = ios::app;
static const ios::openmode IOS_ATE = ios::ate;
static const ios::openmode IOS_BINARY = ios::binary;
static const ios::openmode IOS_IN = ios::in;
static const ios::openmode IOS_OUT = ios::out;
static const ios::openmode IOS_TRUNC = ios::trunc;

/*
 * Class: FE_Iterator
 * ------------------
 * This class is a base class for all Iterators that can work with
 * the foreach construct.  The only purpose of this class is to make
 * it possible to freeing the iterators after they are no longer needed.
 *
 * Note: FE_Iterator is implemented in lexicon.cpp, which is the only
 * iterable class that is not a template class.
 */

class FE_Iterator {
public:
    FE_Iterator();
    ~FE_Iterator();
};

/*
 * Class: FE_State
 * ---------------
 * This class is used to maintain the state of the foreach processing.
 * The class itself is essentially private, but the implementations in
 * the different classes use the fields directly.
 *
 * Note: FE_State is implemented in lexicon.cpp, which is the only
 * iterable class that is not a template class.
 */

class FE_State {
public:
    int state;
    FE_Iterator *iter;

    FE_State();
    ~FE_State();
};

/*
 * Macro: foreach
 * Usage: foreach (type var in collection) { . . . }
 * -------------------------------------------------
 * Provides a much simpler hook to the iterator facility.
 */

#define foreach(arg) \
  for (FE_State _fe; _fe.state < 2; ) \
    for (arg.foreachHook(_fe); _fe.state++ == 1; _fe.state = 0)

#define in =

#endif

main.cpp

#include "stdafx.h"

#include <cstdlib>
#include <string>
#include <iostream>
#include <set>
#include <fstream>

#include "genlib.h"
#include "strutils.h"
#include "simpio.h"
#include "set.h"
#include "lexicon.h"
#include "iterator.h"
#include "foreach.h"

using namespace std;

void PrintRegExpMatches(string exp, Set<string> & matches)
{
    cout << "Activity codes that match " << exp << endl;
    cout << "--------------------------------------" << endl;

    Set<string>::Iterator it = matches.iterator();
    while (it.hasNext()) cout << it.next() << endl;

void PrintCorrections(string seed, int editDistance,
                      Set<Lexicon::CorrectionT> & matches)
{
    cout << "Activity codes that are within " << editDistance << " edits of " << seed << endl;
    cout << "--------------------------------------" << endl;

    Set<Lexicon::CorrectionT>::Iterator it = matches.iterator();
    while (it.hasNext()) {
        Lexicon::CorrectionT corr = it.next();
        cout << corr.suggestedWord << " is a distance of " << corr.editDistance;
        cout << " away." << endl;
forest.peterson
  • 755
  • 2
  • 13
  • 30

2 Answers2

3

It's simple. You have declared, but not defined constructor and destructor for FE_Iterator(). Even though it's base class, you should define them.

JustSomeGuy
  • 3,677
  • 1
  • 23
  • 31
  • so there should be something like FE_Iterator* iter = NULL; at the start and at the end something like if (iter != NULL) delete iter; - I am just copying the code for the Lexicon class from my existing program and changing it for Iterator, I don't really understand it that well – forest.peterson Jun 13 '12 at 22:43
  • No, there should be something like `class A { A() { /* definition here */ } };` (same for destructor) and you have only `class A { A(); ~A() /* no definitions, just declarations */ };` – JustSomeGuy Jun 13 '12 at 23:25
  • I will look this up but help me with the vocab, what is a 'definition' and what is a 'declaration' – forest.peterson Jun 14 '12 at 15:01
  • the definitions are in the .cpp file - so I need to find it? – forest.peterson Jun 14 '12 at 15:29
  • Any idea what the definitions - most likely are? – forest.peterson Jun 20 '12 at 13:55
  • @forest.peterson http://stackoverflow.com/questions/1410563/what-is-the-difference-between-a-definition-and-a-declaration – JustSomeGuy Jun 20 '12 at 16:13
  • That answered what the definition and declaration are. Next step: I added brackets to form empty definitions FE_Iterator() { }; and ~FE_Iterator() { }; and now the project compiles without errors. But, the program exe runs, opens, and closes immediately. – forest.peterson Jun 21 '12 at 19:57
  • I read three resources on iterators http://en.wikipedia.org/wiki/Foreach#C.2B.2B ; http://en.wikipedia.org/wiki/Iterator#Implicit_iterators and http://www.cplusplus.com/reference/algorithm/for_each/ to find that the foreach iterator is an implicit iterators and that there is a standard function template for_each(). So I looked at the classes that call foreach.h and found that they all call the Class: FE_State Macro: foreach, which is defined in foreach.h; so does this mean that as long as it is compiling, then foreach.h is working and there is not a missing .cpp file – forest.peterson Jun 22 '12 at 00:29
1

So this is a weird coincidence, but I worked with Eric Roberts on an updated version of the foreach code that doesn't require a separate .cpp file. The new version of the file is right here, and this should compile without any linker errors:

#ifndef Foreach_Included
#define Foreach_Included

#include <iterator>
#include <map>
#include <cstddef>
#include <cstring>

/* These #includes are for files that contain "in" as a token */

#include <ios>
#include <fstream>
#include <sstream>
using namespace std;

/* Redefine the ios constants (one of which is "in") */

static const ios::openmode IOS_APP = ios::app;
static const ios::openmode IOS_ATE = ios::ate;
static const ios::openmode IOS_BINARY = ios::binary;
static const ios::openmode IOS_IN = ios::in;
static const ios::openmode IOS_OUT = ios::out;
static const ios::openmode IOS_TRUNC = ios::trunc;

/* Private implementation namespace */

namespace _fe {
   struct Range {
      virtual ~Range() { };
   };

   template <typename T>
   struct ArrayRange : Range {
      ArrayRange(const T *begin, const T *end) : iter(begin), end(end) { }
      const T *iter;
      const T *end;
   };

   template <typename CType>
   struct CRange : Range {
      CRange(const CType& c) :
         cont(c), iter(cont.begin()), end(cont.end()) { }
      CType cont;
      typename CType::iterator iter, end;
   };

   template <typename KT, typename VT, typename CT, typename AT>
   struct MapRange : Range {
      MapRange(const map<KT,VT,CT,AT> & c) :
         cont(c), iter(cont.begin()), end(cont.end()) { }
      map<KT,VT,CT,AT> cont;
      typename map<KT,VT,CT,AT>::iterator iter, end;
   };

/*
 * The State struct glues together all of these pieces and
 * stores all of the information throughout the loops.
 */

   struct State {
      State() : state(0), itr(NULL) { }
      ~State() { delete itr; }
      int state;
      Range *itr;
   };

/* General hook function */

   template <typename DowncastType, typename ValueType>
   ValueType HookImpl(State& fe) {
      DowncastType *ip = (DowncastType *) fe.itr;
      if (ip->iter == ip->end) {
         fe.state = 2;
         return ValueType();
      }
      fe.state = 1;
      ValueType vp = *ip->iter;     /* Subtle implementation note:    */
      ++ip->iter;                   /* Using *ip->iter++ here would   */
      return vp;                    /* require copying the iterator.  */
   }

/* Foreach implementation for containers */

   template <typename CType>
   CRange<CType> *Init(State & fe, const CType & collection) {
      fe.itr = new CRange<CType>(collection);
      return (CRange<CType>*) fe.itr;
   }

   template <typename CType>
   typename iterator_traits<typename CType::iterator>::value_type
   Hook(State & fe, CRange<CType> *) {
      return HookImpl<CRange<CType>,
         typename iterator_traits<typename CType::iterator>::value_type>(fe);
   }

/* For maps */

   template <typename K, typename V, typename C, typename A>
   MapRange<K,V,C,A> *Init(State & fe, const map<K,V,C,A> & collection) {
      fe.itr = new MapRange<K,V,C,A>(collection);
      return (MapRange<K,V,C,A>*) fe.itr;
   }

   template <typename DowncastType, typename ValueType>
   ValueType MapHookImpl(State & fe) {
      DowncastType *ip = (DowncastType *) fe.itr;
          if (ip->iter == ip->end) {
         fe.state = 2;
         return ValueType();
      }
      fe.state = 1;
      ValueType key = ip->iter->first;
      ++ip->iter;
      return key;
   }

   template <typename K, typename V, typename C, typename A>
   K Hook(State & fe, MapRange<K,V,C,A> *) {
      return MapHookImpl<MapRange<K,V,C,A>,K>(fe);
   }

/* For C strings */

   template <size_t n>
   ArrayRange<char> *Init(State & fe, char (&str)[n]) {
      fe.itr = new ArrayRange<char>(str, str + strlen(str));
      return (ArrayRange<char>*) fe.itr;
   }

   template <size_t n>
   ArrayRange<char> *Init(State & fe, const char (&str)[n]) {
      fe.itr = new ArrayRange<char>(str, str + strlen(str));
      return (ArrayRange<char>*) fe.itr;
   }

/* For arrays */

   template <typename T, size_t n>
   ArrayRange<T> *Init(State & fe, T (&arr)[n]) {
      fe.itr = new ArrayRange<T>(arr, arr + n);
      return (ArrayRange<T>*) fe.itr;
   }

   template <typename T, size_t n>
   ArrayRange<T> *Init(State & fe, const T (&arr)[n]) {
      fe.itr = new ArrayRange<T>(arr, arr + n);
      return (ArrayRange<T>*) fe.itr;
   }

   template <typename T>
   T Hook(State& fe, ArrayRange<T>*) {
      return HookImpl<ArrayRange<T>, T>(fe);
   }

}

/* The actual foreach and in macros */

#define foreach(arg) \
   for (_fe::State _fe; _fe.state < 2; ) \
      for (arg)); _fe.state++ == 1; _fe.state = 0)

#define in = _fe::Hook(_fe, _fe.state != 0 ? NULL : _fe::Init(_fe,

#endif

Hope this helps!

templatetypedef
  • 362,284
  • 104
  • 897
  • 1,065
  • the open learning initiative by the CS dept is gaining traction, so hopefully my posts will help those students when they search for similar questions about the 106 library. – forest.peterson Jun 13 '12 at 22:54
  • The linker errors are gone, but now there are a bunch of compiler errors in the other class files: vector.h, bst.h, and set.h – forest.peterson Jun 13 '12 at 23:04
  • Have you downloaded the new set of libraries? The current quarter's CS106B class uses updated libraries that are much easier to use. If you download one of the new project files, then everything should just work out of the box. Check out cs106b.stanford.edu for more details. – templatetypedef Jun 13 '12 at 23:04
  • I don't see the class files there - most of the ones I have now I pulled from sourceforge, a couple from lecture notes, and a few from http://code.google.com/p/stanford/source/checkout - i'd just like a set of classes that compile. I don't understand that my program compiled after the class when i rewrote it for case studies that preceded my experiment, but now it does not compile. i don't know enough to know, so i am just pulling together the class files and trying to get them to compile. – forest.peterson Jun 13 '12 at 23:20
  • without a full library of classes available as the .h and .cpp files, not a .lib, I (and everyone else following the class) am forced to build my own set and debug here. – forest.peterson Jun 14 '12 at 15:02
  • I just read this http://stackoverflow.com/questions/4764858/foreach-not-recognized-in-c I am another student that thought they were learning C++ and is now trying to write C++ for implementing my thesis experiment. But, now I found that I do not know C++? It is OK, I understand the need to focus on a topic and abstracting the rest away. So, here I am on stackoverflow trying to complete my knowledge about my favorite language C++. Question 1: is there a .cpp file for the foreach.h version "Last modified on Thu Jun 11 12:04:09 2009 by eroberts" and can you post a copy here? – forest.peterson Jun 14 '12 at 15:47
  • I graphically mapped part of the CS106B class library in yED http://stanford.edu/~granite/confusion/CS106B_library_partial.html if I use your revised foreach.h then vector.h, bst.h, and set.h must be revised. To avoid this, I'd like to use the 2009 version of foreach.h and try to correct the linker error I posted. – forest.peterson Jun 14 '12 at 22:00
  • @forest.peterson- I guess I'm not sure why you want to use the older versions of the libraries when the newer versions are much easier to use. Is there a particular reason that you want to use the old library versions? – templatetypedef Jun 14 '12 at 22:01
  • yes, I already wrote and validated with case studies a program using them - I am now validating the approach with a real world field experiment. – forest.peterson Jun 14 '12 at 22:35
  • I just gave the new library a try from cs106b.stanford.edu, and it is not a straight forward switch-over. There are 77 compiler errors and I already resolved a dozen - mostly relating to source files missing from the new library. As I fix one it snowballs into another bunch of issues. – forest.peterson Jun 14 '12 at 22:57
  • Is There Anybody Out There? I am still struggling with this error. The new foreach code was a good try but it requires using the new library source files. The foreach construct and destruct are the last two errors. – forest.peterson Jun 20 '12 at 05:39
  • @templatetypedef- do you have a copy of foreach.cpp? – forest.peterson Jun 20 '12 at 13:55