【问题标题】:What is wrong with template definition?模板定义有什么问题?
【发布时间】:2020-08-03 01:10:37
【问题描述】:

我在以下用于记忆化的模板类的定义中遇到许多 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;
};

我在 Windows 上的 Eclipse 下编译时收到以下错误消息:

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 )

这个定义有什么问题?

【问题讨论】:

  • 请分享实际的错误信息。
  • map.find( K ) 不起作用。 K 是一种类型。
  • unordered_map...的参数K有很多限制,你不应该是using namespace std;
  • map( unordered_map&lt; K, V &gt;( 4 * n / 3 ) ) 可以简单地为map(4 * n / 3 )。

标签: c++ templates iterator


【解决方案1】:

您有几个问题。首先,您对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 在评论中指出的那样。

【讨论】:

  • 或者干脆auto iter = map.find( key ); :)
【解决方案2】:

这是您的代码的完整工作副本。我只是修复了编译问题,没有进行任何清理或改进代码。 (在 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);
}

【讨论】:

  • 您应该解释您必须更改哪些代码才能使其工作,以及为什么。此外,代码无法在 gcc 或 clang 上编译:coliru.stacked-crooked.com/a/b09083ab0c343da1
  • @NathanOliver 感谢您的评论。我修复了 Linux 上的编译问题。
猜你喜欢
  • 1970-01-01
  • 2017-04-10
  • 1970-01-01
  • 2018-12-14
  • 2019-11-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多