2015-11-26 3 views
-2

Я получаю ошибку, указанную в ошибке заголовка при попытке скомпилировать. Что я делаю не так? Я пытаюсь реализовать шаблонный класс HashTable < K, V> :: prime_below (unsigned long n). Но компилятор отказывается мне позволить.Почему я получаю эту ошибку? ожидаемый инициализатор до '<' token

#ifndef HASHTABLE_H 
#define HASHTABLE_H 
#include <list> 
#include <string> 
#include <vector> 
#include <utility> 
#include <iostream> 


static const unsigned int max_prime = 1301081; 

static const unsigned int default_capacity = 11; 

namespace cop4530 
{ 
    template <typename K, typename V> 
    class HashTable 
    { 
    public: 
     HashTable(); 
     HashTable(size_t size = 101); 
     ~HashTable(); 

     bool contains(const K & k); 

     bool match(const std::pair<K, V> &kv) const; 


     bool insert(const std::pair<K, V> &kv); 

     bool insert(std::pair<K, V> && kv); 

     bool remove(const K & k); 

     void clear(); 

     bool load(const char *filename); 

     void dump(); 

     bool write_to_file(const char* filename); 

    private: 
     void makeEmpty(); 

     void rehash(); 

     unsigned long prime_below(unsigned long n); 
     void setPrimes(std::vector<unsigned long> & vprimes); 


    }; 

#include "HashTable.hpp" 

} 

#endif 

Ниже приведен файл hpp. Так мой инструктор требует, чтобы мы реализовали файл заголовка.

template <typename K, typename V> 
HashTable<K,V>::HashTable(size_t) 
{ 

} 

template <typename K, typename V> 
unsigned long HashTable<K,V>::prime_below (unsigned long n) 
{ 
    if (n > max_prime) 
    { 
     std::cerr << "** input too large for prime_below()\n"; 
     return 0; 
    } 
    if (n == max_prime) 
    { 
     return max_prime; 
    } 
    if (n <= 1) 
    { 
    std::cerr << "** input too small \n"; 
     return 0; 
    } 

    // now: 2 <= n < max_prime 
    std::vector <unsigned long> v (n+1); 
    setPrimes(v); 
    while (n > 2) 
    { 
     if (v[n] == 1) 
    return n; 
     --n; 
    } 

    return 2; 
} 

//Sets all prime number indexes to 1. Called by method prime_below(n) 
template <typename K, typename V> 
void HashTable<K, V>::setPrimes(std::vector<unsigned long>& vprimes) 
{ 
    int i = 0; 
    int j = 0; 

    vprimes[0] = 0; 
    vprimes[1] = 0; 
    int n = vprimes.capacity(); 

    for (i = 2; i < n; ++i) 
    vprimes[i] = 1; 

    for(i = 2; i*i < n; ++i) 
    { 
     if (vprimes[i] == 1) 
     for(j = i + i ; j < n; j += i) 
      vprimes[j] = 0; 
    } 
} 

Вот основной файл Ниже

#include "HashTable.h" 

using namespace std; 
using namespace cop4530; 

int main() 
{ 
    HashTable<int, string> t(10); 
    return 0; 
} 

компиляцией команд и результаты

1) г ++ -std = C++ 11 -Wall -pedantic HashTable.h - компилировать Fine

2) g ++ -std = C++ 11 -Wall -pedantic HashTable.hpp -

HashTable.hpp:6:1: error: ‘HashTable’ does not name a type 
HashTable<K,V>::HashTable(size_t) 
^ 
HashTable.hpp:12:24: error: expected initializer before ‘<’ token 
unsigned long HashTable<K,V>::prime_below (unsigned long n) 
         ^
HashTable.hpp:44:15: error: expected initializer before ‘<’ token 
void HashTable<K, V>::setPrimes(std::vector<unsigned long>& vprimes) 

3) г ++ -std = C++ -Wall -pedantic main.cpp

/tmp/ccMVi6jr.o: I 

n function `main': 
main.cpp:(.text+0x36): undefined reference to `cop4530::HashTable<int, std::string>::HashTable(unsigned long)' 
main.cpp:(.text+0x47): undefined reference to `cop4530::HashTable<int, std::string>::~HashTable()' 
collect2: error: ld returned 1 exit status 
+0

Почему вы '#include" HashTable.hpp "в заголовке? Вы включаете его в '.cpp'? – TartanLlama

+0

Это требование моего профессора. Файл hpp является расширением .h-файла. Я думаю, вы можете сказать, что он заменяет файл .cpp. Я все еще не уверен на 100%, почему он требует от нас этого, я даже читал, что это плохая практика, но это то, о чем он просил об этом задании. – user5607673

+0

Вам просто нужно любить таких профессоров ... – DevSolar

ответ

2

Это просто неправильно:

g++ -std=c++11 -Wall -pedantic HashTable.hpp 

Эти ошибки вы получаете:

HashTable.hpp:6:1: error: ‘HashTable’ does not name a type 
HashTable<K,V>::HashTable(size_t) 
^ 
HashTable.hpp:12:24: error: expected initializer before ‘<’ token 
unsigned long HashTable<K,V>::prime_below (unsigned long n) 
        ^

Эта ошибка должна быть достаточно ясной. HashTable не называет тип. Он не называет тип, потому что он не объявлен. Он не объявлен, потому что объявление находится в HashTable.h. Все другие ошибки также связаны с тем, что HashTable не определен.

HashTable.hpp зависит от определений в HashTable.h и не полезен им самостоятельно. Это просто файл заголовка, и нет смысла пытаться его скомпилировать.

Это также бессмысленно:

g++ -std=c++11 -Wall -pedantic HashTable.h 

Потому что это также заголовок.

Это правильно (за опечатку в -std аргумента за исключением):

g++ -std=c++ -Wall -pedantic main.cpp 

Но как ваш компоновщик говорит вам:

n function `main': 
main.cpp:(.text+0x36): undefined reference to `cop4530::HashTable<int, std::string>::HashTable(unsigned long)' 
main.cpp:(.text+0x47): undefined reference to `cop4530::HashTable<int, std::string>::~HashTable()' 
collect2: error: ld returned 1 exit status 

Вы не определили все функции-члены шаблон шаблона.

+0

То, что вы сказали, имеет смысл. Не уверен, что им не хватает. Я прокомментировал все в файле .h, кроме моего конструктора и деструктора, чтобы убедиться, что шаблон класса определен и протестирован в основном. Но я не могу понять, почему HashTable не называет тип. Я использовал разрешение области, чтобы определить в нем файл .hpp. Я использовал шаблон . Теперь его высказывание «HashTable не было определено в этой области». Я знаю, что это простое решение, его разочарование я уже не указал. – user5607673

+0

@ user5607673 Файл .h является тем, который определяет шаблон. Если вы прокомментируете все, кроме конструктора и деструктора, то у вас больше нет определения самого шаблона. HashTable не указывает тип в файле .hpp, только если он не включен в файл .h, который определяет HashTable. Код в вопросе представляется в основном правильным с точки зрения определений, за исключением того, что определение деструктора не существует. – user2079303

Смежные вопросы