Что не так с определением шаблона? - PullRequest
0 голосов
/ 20 апреля 2020

Я получаю многочисленные ошибки C ++ в следующем определении класса шаблона для запоминания:

template < typename K, typename V > class Memo{
public:
    Memo( int n ) : map( unordered_map< K, V >( 4 * n / 3 ) ) {}
    bool contains( K key ) { return map.find( K ) != map.end(); }
    V* get( K key ) {
        unordered_map< K, V >::iterator iter;
        iter = map.find( K );
        if ( map.end() != iter )
            return &( iter->second );
        else
            return NULL;
    }
private:
    unordered_map< K, V > map;
};

Я получаю следующие сообщения об ошибках, компилируемые в Eclipse на Windows:

g++ -std=c++0x -O3 -Wall -c -fmessage-length=0 -o "src\\XorQuadruples.o" "..\\src\\XorQuadruples.cpp" 
..\src\XorQuadruples.cpp: In member function 'bool Memo<K, V>::contains(K)':
..\src\XorQuadruples.cpp:60:59: error: expected primary-expression before ')' token
  bool contains( K key ) { return map.end() != map.find( K ); }
                                                           ^
..\src\XorQuadruples.cpp: In member function 'V* Memo<K, V>::get(K)':
..\src\XorQuadruples.cpp:62:3: error: need 'typename' before 'std::unordered_map<K, V>::iterator' because 'std::unordered_map<K, V>' is a dependent scope
   unordered_map< K, V >::iterator iter = map.find( K );
   ^
..\src\XorQuadruples.cpp:62:35: error: expected ';' before 'iter'
   unordered_map< K, V >::iterator iter = map.find( K );
                                   ^
..\src\XorQuadruples.cpp:63:21: error: 'iter' was not declared in this scope
   if ( map.end() != iter )

Что не так с этим определением?

Ответы [ 2 ]

1 голос
/ 20 апреля 2020

У вас есть пара вопросов. Во-первых, ваш вызов find() нуждается в значении, а не в типе. Во-вторых, объявлению переменной iter должно предшествовать typename, поскольку оно находится в зависимом контексте.

Исправление этих проблем выглядит следующим образом:

 bool contains( K key ) { return map.find( key ) != map.end(); }  // use key
    V* get( K key ) {
        typename unordered_map< K, V >::iterator iter;  // say typename
        iter = map.find( key );                        // use key
// ...

Чтобы избежать необходимости Изложив ключевое слово typename, вы можете попросить компилятор определить тип, например:

auto iter = map.find(key);

, как @ Jarod42 указал в комментарии.

0 голосов
/ 20 апреля 2020

Это полная рабочая копия вашего кода. Я просто исправил проблемы компиляции, без какой-либо очистки или улучшения кода. (Проверено на VS2015)

#include <unordered_map>

using namespace std;

template <typename K, typename V > 
class Memo 
{
public:
   Memo(int n) : map(unordered_map< K, V >(4 * n / 3)) {}
   bool contains(K key) 
   { 
      return map.find(key) != map.end(); 
   }

   V* get(K key) 
   {
      typename unordered_map< K, V >::iterator iter;
      iter = map.find(key);
      if (map.end() != iter)
         return &(iter->second);
      else
         return NULL;
   }
private:
   unordered_map< K, V > map;
};


int main()
{
   Memo<int, double> mem(10);

   bool x = mem.contains(12);
   auto y = mem.get(13);
}
...