C++ cs106b library vector.cpp错误C2143:语法错误:缺少'';在'之前<';

C++ cs106b library vector.cpp错误C2143:语法错误:缺少'';在'之前<';,c++,vector,C++,Vector,与向量有关:向量(整数容量) C2143:语法错误:缺少“;”在“之前,无论其名称如何,都不能从该项目编译vector.cpp。.CPP文件只存在于vector.h中的#included 不知何故,您正在直接编译vector.cpp。错误消息源于缺少模板类向量{…}的定义,类向量在哪里定义?在stdafx.h包含的某些头文件中,它是在使用它的类中定义的;我编辑了这篇文章以包含examplevector.cpp作为源文件,是否应该将其排除在外,但保留在与项目相同的文件夹中?为什么会这样,所以我不

与向量有关:向量(整数容量)


  • C2143:语法错误:缺少“;”在“之前,无论其名称如何,都不能从该项目编译vector.cpp。.CPP文件只存在于vector.h中的
    #include
    d


    不知何故,您正在直接编译vector.cpp。错误消息源于缺少
    模板类向量{…}

    的定义,类
    向量在哪里定义?在stdafx.h包含的某些头文件中,它是在使用它的类中定义的;我编辑了这篇文章以包含examplevector.cpp作为源文件,是否应该将其排除在外,但保留在与项目相同的文件夹中?为什么会这样,所以我不能再犯这个错误了。创建这个库的人使用了一种非典型的命名约定。在他们的方案中,vector.cpp应该位于“include/private/vector.cpp”中(我认为它不是“与项目相同的文件夹”)。不应编译该目录中的任何CPP文件。(根据您对IDE或构建系统的选择,您可能需要“排除”这些文件。)编译器为VS2008;为什么从编译器中排除私有文件?我排除了所有私有文件,包括私有头。您对这些被排除在外的“原因”有简短的解释吗?简短的解释:因为它们是(名称不正确的)标题。
    
    /*
     * File: private/vector.cpp
     * Last modified on Fri Jun  5 16:19:42 2009 by eroberts
     * -----------------------------------------------------
     * This file contains the implementation of the vector.h interface.
     * Because of the way C++ compiles templates, this code must be
     * available to the compiler when it reads the header file.
     */
    
    #ifdef _vector_h
    
    #include "stdafx.h"
    
    /*
     * Vector class implementation
     * ---------------------------
     * The Vector is internally managed as a dynamic array of elements.
     * It tracks capacity (numAllocated) separately from size (numUsed).
     * All access is bounds-checked for safety.
     */
    
    template <typename ElemType>
    Vector<ElemType>::Vector(int capacity) {
        elements = new ElemType[capacity];
        numAllocated = capacity;
        numUsed = 0;
        timestamp = 0L;
    }
    
    template <typename ElemType>
    Vector<ElemType>::~Vector() {
        if (elements != NULL) delete[] elements;
    }
    
    template <typename ElemType>
    inline int Vector<ElemType>::size() {
        return numUsed;
    }
    
    template <typename ElemType>
    bool Vector<ElemType>::isEmpty() {
        return size() == 0;
    }
    
    template <typename ElemType>
    ElemType Vector<ElemType>::getAt(int index) {
        checkRange(index, "getAt");
        return elements[index];
    }
    
    template <typename ElemType>
    void Vector<ElemType>::setAt(int index, ElemType elem) {
        checkRange(index, "setAt");
        elements[index] = elem;
    }
    
    /* Private method: checkRange
     * --------------------------
     * Verifies that index is in range for this vector, if not, raises an
     * error.  The verb string is used in the error message to describe the
     * operation that caused the range error, .e.g "setAt" or "removeAt".
     */
    
    template <typename ElemType>
    inline void Vector<ElemType>::checkRange(int index, const char *verb) {
        if (index < 0 || index >= size()) {
            Error("Attempt to " + string(verb) + " index "
                  + IntegerToString(index) + " in a vector of size "
                  + IntegerToString(size()) + ".");
        }
    }
    
    template <typename ElemType>
    inline ElemType &Vector<ElemType>::operator[](int index) {
        checkRange(index, "access");
        return elements[index];
    }
    
    template <typename ElemType>
    void Vector<ElemType>::add(ElemType elem) {
        insertAt(numUsed, elem);
    }
    
    template <typename ElemType>
    void Vector<ElemType>::insertAt(int index, ElemType elem) {
        if (numAllocated == numUsed) enlargeCapacity();
        if (index != numUsed) checkRange(index, "insertAt");
        for (int i = numUsed; i > index; i--) {
            elements[i] = elements[i-1];
        }
        elements[index] = elem;
        numUsed++;
        timestamp++;
    }
    
    template <typename ElemType>
    void Vector<ElemType>::removeAt(int index) {
        checkRange(index, "removeAt");
        for (int i = index; i < numUsed-1; i++) {
            elements[i] = elements[i+1];
        }
        numUsed--;
        timestamp++;
    }
    
    template <typename ElemType>
    void Vector<ElemType>::clear() {
        delete[] elements;
        elements = NULL;
        numUsed = numAllocated = 0;
        timestamp++;
    }
    
    template <typename ElemType>
    const Vector<ElemType> &Vector<ElemType>::operator=(const Vector & rhs) {
        if (this != &rhs) {
            clear();
            copyInternalData(rhs);
            timestamp = 0L;
        }
        return *this;
    }
    
    template <typename ElemType>
    Vector<ElemType>::Vector(const Vector & rhs) {
        copyInternalData(rhs);
        timestamp = 0L;
    }
    
    template <typename ElemType>
    void Vector<ElemType>::mapAll(void (*fn)(ElemType)) {
        long t0 = timestamp;
        for (int i = 0; i < numUsed; i++) {
            if (timestamp != t0) {
                Error("Vector structure has been modified");
            }
            fn(elements[i]);
        }
    }
    
    template <typename ElemType>
    template <typename ClientDataType>
    void Vector<ElemType>::mapAll(void (*fn)(ElemType, ClientDataType&),
                                  ClientDataType & data) {
        long t0 = timestamp;
        for (int i = 0; i < numUsed; i++) {
            if (timestamp != t0) {
                Error("Vector structure has been modified");
            }
            fn(elements[i], data);
        }
    }
    
    /*
     * Vector::Iterator class implementation
     * ----------------------------------
     * The Iterator for Vector maintains a pointer to the original Vector and
     * an index into that vector that identifies the next element to return.
     */
    
    template <typename ElemType>
    Vector<ElemType>::Iterator::Iterator() {
        vp = NULL;
    }
    
    template <typename ElemType>
    typename Vector<ElemType>::Iterator Vector<ElemType>::iterator() {
        return Iterator(this);
    }
    
    template <typename ElemType>
    Vector<ElemType>::Iterator::Iterator(Vector *vecRef) {
        vp = vecRef;
        curIndex = 0;
        timestamp = vp->timestamp;
    }
    
    template <typename ElemType>
    bool Vector<ElemType>::Iterator::hasNext() {
        if (vp == NULL) Error("hasNext called on uninitialized iterator");
        if (timestamp != vp->timestamp) {
            Error("Vector structure has been modified");
        }
        return curIndex < vp->size();
    }
    
    template <typename ElemType>
    ElemType Vector<ElemType>::Iterator::next() {
        if (vp == NULL) Error("next called on uninitialized iterator");
        if (!hasNext()) {
            Error("Attempt to get next from iterator"
                  " where hasNext() is false");
        }
        return (*vp)[curIndex++];
    }
    
    template <typename ElemType>
    ElemType Vector<ElemType>::foreachHook(FE_State & fe) {
        if (fe.state == 0) fe.iter = new Iterator(this);
        if (((Iterator *) fe.iter)->hasNext()) {
            fe.state = 1;
            return ((Iterator *) fe.iter)->next();
        } else {
            fe.state = 2;
            return ElemType();
        }
    }
    
    /* Private method: enlargeCapacity
     * -------------------------------
     * Doubles the current capacity of the vector's internal storage,
     * copying all existing values.
     */
    
    template <typename ElemType>
    void Vector<ElemType>::enlargeCapacity() {
        numAllocated = (numAllocated == 0 ? 10 : numAllocated*2);
        ElemType *newArray = new ElemType[numAllocated];
        for (int i = 0; i < numUsed; i++) {
            newArray[i] = elements[i];
        }
        delete[] elements;
        elements = newArray;
    }
    
    /* Private method: copyInternalData
     * --------------------------------
     * Common code factored out of the copy constructor and operator= to
     * copy the contents from the other vector.
     */
    
    template <typename ElemType>
    void Vector<ElemType>::copyInternalData(const Vector & other) {
        elements = new ElemType[other.numUsed];
        for (int i = 0; i < other.numUsed; i++) {
            elements[i] = other.elements[i];
        }
        numUsed = other.numUsed;
        numAllocated = other.numUsed;
    }
    
    #endif
    
    /*
     * File: set.h
     * Last modified on Thu Jun 11 09:17:43 2009 by eroberts
     *      modified on Tue Jan  2 14:34:06 2007 by zelenski
     * -----------------------------------------------------
     * This interface file contains the Set class template, a
     * collection for efficiently storing a set of distinct elements.
     */
    
    #ifndef _set_h
    #define _set_h
    
    #include "cmpfn.h"
    #include "bst.h"
    #include "vector.h"
    #include "foreach.h"
    
    /*
     * Class: Set
     * ----------
     * This interface defines a class template that stores a collection of
     * distinct elements, using a sorted relation on the elements to
     * provide efficient managaement of the collection.
     * For maximum generality, the Set is supplied as a class template.
     * The element type is determined by the client. The client configures
     * the set to hold values of a specific type, e.g. Set<int> or
     * Set<studentT>. The one requirement on the element type is that the
     * client must supply a comparison function that compares two elements
     * (or be willing to use the default comparison function that uses
     * the built-on operators  < and ==).
     */
    
    template <typename ElemType>
    class Set {
    
    public:
    
    /* Forward references */
        class Iterator;
    
    /*
     * Constructor: Set
     * Usage: Set<int> set;
     *        Set<student> students(CompareStudentsById);
     *        Set<string> *sp = new Set<string>;
     * -----------------------------------------
     * The constructor initializes an empty set. The optional
     * argument is a function pointer that is applied to
     * two elements to determine their relative ordering. The
     * comparison function should return 0 if the two elements
     * are equal, a negative result if first is "less than" second,
     * and a positive resut if first is "greater than" second. If
     * no argument is supplied, the OperatorCmp template is used as
     * a default, which applies the bulit-in < and == to the
     * elements to determine ordering.
     */
        Set(int (*cmpFn)(ElemType, ElemType) = OperatorCmp);
    
    /*
     * Destructor: ~Set
     * Usage: delete sp;
     * -----------------
     * The destructor deallocates  storage associated with set.
     */
        ~Set();
    
    /*
     * Method: size
     * Usage: count = set.size();
     * --------------------------
     * This method returns the number of elements in this set.
     */
        int size();
    
    /*
     * Method: isEmpty
     * Usage: if (set.isEmpty())...
     * ----------------------------
     * This method returns true if this set contains no
     * elements, false otherwise.
     */
        bool isEmpty();
    
    /*
     * Method: add
     * Usage: set.add(value);
     * ----------------------
     * This method adds an element to this set. If the
     * value was already contained in the set, the existing entry is
     * overwritten by the new copy, and the set's size is unchanged.
     * Otherwise, the value is added and set's size increases by one.
     */
        void add(ElemType elem);
    
    /*
     * Method: remove
     * Usage: set.remove(value);
     * -----------------------
     * This method removes an element from this set. If the
     * element was not contained in the set, the set is unchanged.
     * Otherwise, the element is removed and the set's size decreases
     * by one.
     */
        void remove(ElemType elem);
    
    /*
     * Method: contains
     * Usage: if (set.contains(value))...
     * -----------------------------------
     * Returns true if the element in this set, false otherwise.
     */
        bool contains(ElemType elem);
    
    /*
     * Method: find
     * Usage: eptr = set.find(elem);
     * -----------------------------
     * If the element is contained in this set, returns a pointer
     * to that elem.  The pointer allows you to update that element
     * in place. If element is not contained in this set, NULL is
     * returned.
     */
        ElemType *find(ElemType elem);
    
    /*
     * Method: equals
     * Usage: if (set.equals(set2)) . . .
     * -----------------------------------
     * This predicate function implements the equality relation
     * on sets.  It returns true if this set and set2 contain
     * exactly the same elements, false otherwise.
     */
        bool equals(Set & otherSet);
    
    /*
     * Method: isSubsetOf
     * Usage: if (set.isSubsetOf(set2)) . . .
     * --------------------------------------
     * This predicate function implements the subset relation
     * on sets.  It returns true if all of the elements in this
     * set are contained in set2.  The set2 does not have to
     * be a proper subset (that is, it may be equals).
     */
        bool isSubsetOf(Set & otherSet);
    
    /*
     * Methods: unionWith, intersectWith, subtract
     * Usage: set.unionWith(set2);
     *        set.intersectWith(set2);
     *        set.subtract(set2);
     * -------------------------------
     * These fmember unctions modify the receiver set as follows:
     *
     * set.unionWith(set2);      Adds all elements from set2 to this set.
     * set.intersectWith(set2);  Removes any element not in set2 from this set.
     * set.subtract(set2);       Removes all element in set2 from this set.
     */
        void unionWith(Set & otherSet);
        void intersectWith(Set & otherSet);
        void subtract(Set & otherSet);
    
    /*
     * Method: clear
     * Usage: set.clear();
     * -------------------
     * This method removes all elements from this set. The
     * set is made empty and will have size() = 0 after being cleared.
     */
        void clear();
    
    /*
     * SPECIAL NOTE: mapping/iteration support
     * ---------------------------------------
     * The set supports both a mapping operation and an iterator which
     * allow the client access to all elements one by one.  In general,
     * these  are intended for _viewing_ elements and can behave
     * unpredictably if you attempt to modify the set's contents during
     * mapping/iteration.
     */
    
    /*
     * Method: mapAll
     * Usage: set.mapAll(Print);
     * -------------------------
     * This method iterates through this set's contents
     * and calls the function fn once for each element.
     */
        void mapAll(void (*fn)(ElemType elem));
    
    /*
     * Method: mapAll
     * Usage: set.mapAll(PrintToFile, outputStream);
     * --------------------------------------------
     * This method iterates through this set's contents
     * and calls the function fn once for each element, passing
     * the element and the client's data. That data can be of whatever
     * type is needed for the client's callback.
     */
        template <typename ClientDataType>
        void mapAll(void (*fn)(ElemType elem, ClientDataType & data),
                    ClientDataType & data);
    
    /*
     * Method: iterator
     * Usage: iter = set.iterator();
     * -----------------------------
     * This method creates an iterator that allows the client to
     * iterate through the elements in this set.  The elements are
     * returned in the order determined by the comparison function.
     *
     * The idiomatic code for accessing elements using an iterator is
     * to create the iterator from the collection and then enter a loop
     * that calls next() while hasNext() is true, like this:
     *
     *     Set<int>::Iterator iter = set.iterator();
     *     while (iter.hasNext()) {
     *         int value = iter.next();
     *         . . .
     *     }
     *
     * This pattern can be abbreviated to the following more readable form:
     *
     *     foreach (int value in set) {
     *         . . .
     *     }
     *
     * To avoid exposing the details of the class, the definition of the
     * Iterator class itself appears in the private/set.h file.
     */
        Iterator iterator();
    
    private:
    
    #include "private/set.h"
    
    };
    
    #include "private/set.cpp"
    
    #endif
    
    /*
     * File: private/vector.h
     * Last modified on Fri Jun  5 15:39:26 2009 by eroberts
     * -----------------------------------------------------
     * This file contains the private section of the vector.h interface.
     * This portion of the class definition is taken out of the vector.h
     * header so that the client need not have to see all of these
     * details.
     */
    
    public:
    
    /*
     * Class: Vector<ElemType>::Iterator
     * ---------------------------------
     * This interface defines a nested class within the Vector template that
     * provides iterator access to the Vector contents.
     */
        class Iterator : public FE_Iterator {
        public:
            Iterator();
            bool hasNext();
            ElemType next();
    
        private:
            Iterator(Vector *vecRef);
            Vector *vp;
            int curIndex;
            long timestamp;
            friend class Vector;
        };
        friend class Iterator;
        ElemType foreachHook(FE_State & _fe);
    
    /*
     * Deep copying support
     * --------------------
     * This copy constructor and operator= are defined to make a
     * deep copy, making it possible to pass/return vectors by value
     * and assign from one vector to another. The entire contents of
     * the vector, including all elements, are copied. Each vector
     * element is copied from the original vector to the copy using
     * assignment (operator=). Making copies is generally avoided
     * because of the expense and thus, vectors are typically passed
     * by reference, however, when a copy is needed, these operations
     * are supported.
     */
        const Vector & operator=(const Vector & rhs);
        Vector(const Vector & rhs);
    
    private:
        ElemType *elements;
        int numAllocated, numUsed;
        long timestamp;
    
        void checkRange(int index, const char *msg);
        void enlargeCapacity();
        void copyInternalData(const Vector & other);
    
    /*
     * File: vector.h
     * Last modified on Fri Jun  5 15:35:35 2009 by eroberts
     *      modified on Tue Jan  2 13:56:15 2007 by zelenski
     * -----------------------------------------------------
     * This interface file contains the Vector class template, an
     * efficient, safer, convenient replacement for the built-in array.
     */
    
    #ifndef _vector_h
    #define _vector_h
    
    #include "genlib.h"
    #include "strutils.h"
    #include "foreach.h"
    
    /*
     * Class: Vector
     * -------------
     * This interface defines a class template that stores a homogeneous
     * indexed collection. The basic operations are similar to those
     * in the built-in array type, with the added features of dynamic
     * memory management, bounds-checking on indexes, and convenient
     * insert/remove operations. Like an array, but better!
     * For maximum generality, the Vector is supplied as a class template.
     * The client specializes the vector to hold values of a specific
     * type, e.g. Vector<int> or Vector<studentT>, as needed
     */
    
    template <typename ElemType>
    class Vector {
    
    public:
    
    /* Forward references */
        class Iterator;
    
    /*
     * Constructor: Vector
     * Usage: Vector<int> vec;
     *        Vector<student> dormlist(200);
     *        Vector<string> *vp = new Vector<string>;
     * -----------------------------------------------
     * The constructor initializes a new empty vector. The optional
     * argument is a hint about the expected number of elements that
     * this vector will hold, which allows vector to configure itself
     * for that capacity during initialization.  If not specified,
     * it is initialized with default capacity and grows as elements
     * are added. Note that capacity does NOT mean size, a newly
     * constructed vector always has size() = 0. A large starting
     * capacity allows you to add that many elements without requiring
     * any internal reallocation. The explicit keyword is required to
     * avoid accidental construction of a vector from an int.
     */
        explicit Vector(int sizeHint = 0);
    
    /*
     * Destructor: ~Vector
     * Usage: delete vp;
     * -----------------
     * The destructor deallocates storage associated with this vector.
     */
        ~Vector();
    
    /*
     * Method: size
     * Usage: nElems = vec.size();
     * ---------------------------
     * This method returns the number of elements in
     * this vector.
     */
        int size();
    
    /*
     * Method: isEmpty
     * Usage: if (vec.isEmpty())...
     * -----------------------------
     * This method returns true if this vector contains no
     * elements, false otherwise.
     */
        bool isEmpty();
    
    /*
     * Method: getAt
     * Usage: val = vec.getAt(3);
     * --------------------------
     * This method returns the element at the specified index
     * in this vector. Elements are indexed starting from 0.  A call to
     * vec.getAt(0) returns the first element, vec.getAt(vec.size()-1)
     * returns the last. Raises an error if index is outside the range
     * [0, size()-1].
     */
        ElemType getAt(int index);
    
    /*
     * Method: setAt
     * Usage: vec.setAt(3, value);
     * ---------------------------
     * This method replaces the element at the specified index
     * in this vector with a new value.  The previous value at that
     * index is overwritten with the new value. The size of the vector
     * is unchanged. Raises an error if index is not within the
     * range [0, size()-1].
     */
        void setAt(int index, ElemType value);
    
    /*
     * Method: operator[]
     * Usage: vec[0] = vec[1];
     * -----------------------
     * This method overloads [] to access elements from
     * this vector. This allows the client to use array-like notation
     * to get/set individual vector elements. Returns a reference to
     * the element to allow in-place modification of values. Raises
     * an error if index is not within the range [0, size()-1].
     */
        ElemType & operator[](int index);
    
    /*
     * Method: add
     * Usage: vec.add(value);
     * ----------------------
     * This method adds an element to the end of this vector.
     * The vector's size increases by one.
     */
        void add(ElemType elem);
    
    /*
     * Method: insertAt
     * Usage: vec.insertAt(0, value);
     * ------------------------------
     * This method inserts the element into this vector at
     * the specified index, shifting all subsequent elements one
     * index higher. A call to vec.insertAt(0, val) inserts a new
     * element at the beginning, vec.insertAt(vec.size(), val) add
     * a new element to the end. The vector's size increases by one.
     * Raises an error if index is outside the range [0, size()].
     */
        void insertAt(int index, ElemType elem);
    
    /*
     * Method: removeAt
     * Usage: vec.removeAt(3);
     * -----------------------
     * This method removes the element at the specified
     * index from this vector, shifting all subsequent elements one
     * index lower. A call to vec.removeAt(0) removes the first
     * element, vec.removeAt(vec.size()-1), removes the last. The
     * vector's size decreases by one. Raises an error if index is
     * outside the range [0, size()-1].
     */
        void removeAt(int index);
    
    /*
     * Method: clear
     * Usage: vec.clear();
     * -------------------
     * This method removes all elements from this vector. The
     * vector is made empty and will have size() = 0.
     */
        void clear();
    
    /*
     * SPECIAL NOTE: mapping/iteration support
     * ---------------------------------------
     * The Vector class supports both a mapping operation and an iterator which
     * allow the client access to all elements one by one.  In general,
     * these  are intended for _viewing_ elements and can behave
     * unpredictably if you attempt to modify the vector's contents during
     * mapping/iteration.
     */
    
    /*
     * Method: mapAll
     * Usage: vector.mapAll(Print);
     * ----------------------------
     * This method iterates through this vector's contents
     * and calls the function fn once for each element.
     */
        void mapAll(void (*fn)(ElemType elem));
    
    /*
     * Method: mapAll
     * Usage: vector.mapAll(PrintToFile, outputStream);
     * ------------------------------------------------
     * This method iterates through this vector's contents
     * and calls the function fn once for each element, passing
     * the element and the client's data. That data can be of whatever
     * type is needed for the client's callback.
     */
        template <typename ClientDataType>
        void mapAll(void (*fn)(ElemType elem, ClientDataType & data),
                    ClientDataType & data);
    
    /*
     * Method: iterator
     * Usage: iter = vector.iterator();
     * --------------------------------
     * This method creates an iterator that allows the client to
     * iterate through the elements in this vector.  The elements are
     * returned in index order.
     *
     * The idiomatic code for accessing elements using an iterator is
     * to create the iterator from the collection and then enter a loop
     * that calls next() while hasNext() is true, like this:
     *
     *     Vector<int>::Iterator iter = vector.iterator();
     *     while (iter.hasNext()) {
     *         int elem = iter.next();
     *         . . .
     *     }
     *
     * This pattern can be abbreviated to the following more readable form:
     *
     *     foreach (int elem in vector) {
     *         . . .
     *     }
     *
     * To avoid exposing the details of the class, the definition of the
     * Iterator class itself appears in the private/vector.h file.
     */
        Iterator iterator();
    
    private:
    
    #include "private/vector.h"
    
    };
    
    #include "private/vector.cpp"
    
    #endif