简体   繁体   English

C++ 使用具有无序 map 的模板类型

[英]C++ using template type with unordered map

I am new to C++ so this is likely a simple mistake but this code is giving me problems for hours now.我是 C++ 的新手,所以这可能是一个简单的错误,但这段代码现在给我带来了几个小时的问题。 I am really just not sure what to try next.我真的只是不确定下一步该尝试什么。

EratosthenesHashMap.h EratosthenesHashMap.h

#pragma once

#include <unordered_map>
#include <boost/functional/hash.hpp>
#include "SieveOfEratosthenes.h"

template<class T>
class EratosthenesHashMap
{

public:
    EratosthenesHashMap(SieveOfEratosthenes& sieve);
    ~EratosthenesHashMap();

    unsigned int addValue(T& value);
    unsigned int getPrime(T& value) const;

private:
    SieveOfEratosthenes *sieve;
    std::unordered_map<T, unsigned int, boost::hash<T>> valueMap;
};

EratosthenesHashMap.cpp EratosthenesHashMap.cpp

#include "EratosthenesHashMap.h"

EratosthenesHashMap<class T>::EratosthenesHashMap(SieveOfEratosthenes& sieve) 
{
    this->sieve = &sieve;
};

unsigned int EratosthenesHashMap<T>::addValue(T& value)
{
    return 0;
}

unsigned int EratosthenesHashMap<T>::getPrime(T& value) const
{
    return 0;
}

Error:错误:

EratosthenesHashMap.cpp
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30037\include\utility(331,10): error C2079: 'std::pair<const T,unsigned int>::first' uses undefined class 'T'
1>        with
1>        [
1>            T=T
1>        ]
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30037\include\xhash(305): message : see reference to class template instantiation 'std::pair<const T,unsigned int>' being compiled
1>        with
1>        [
1>            T=T
1>        ]
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30037\include\xhash(304): message : while compiling class template member function 'void std::_Hash_vec<std::allocator<std::_List_unchecked_iterator<std::_List_val<std::_List_simple_types<_Ty>>>>>::_Tidy(void) noexcept'
1>        with
1>        [
1>            _Ty=std::pair<const T,unsigned int>
1>        ]
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30037\include\xhash(313): message : see reference to function template instantiation 'void std::_Hash_vec<std::allocator<std::_List_unchecked_iterator<std::_List_val<std::_List_simple_types<_Ty>>>>>::_Tidy(void) noexcept' being compiled
1>        with
1>        [
1>            _Ty=std::pair<const T,unsigned int>
1>        ]
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30037\include\xhash(1933): message : see reference to class template instantiation 'std::_Hash_vec<std::allocator<std::_List_unchecked_iterator<std::_List_val<std::_List_simple_types<_Ty>>>>>' being compiled
1>        with
1>        [
1>            _Ty=std::pair<const T,unsigned int>
1>        ]
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30037\include\unordered_map(69): message : see reference to class template instantiation 'std::_Hash<std::_Umap_traits<_Kty,_Ty,std::_Uhash_compare<_Kty,_Hasher,_Keyeq>,_Alloc,false>>' being compiled
1>        with
1>        [
1>            _Kty=T,
1>            _Ty=unsigned int,
1>            _Hasher=boost::hash<T>,
1>            _Keyeq=std::equal_to<T>,
1>            _Alloc=std::allocator<std::pair<const T,unsigned int>>
1>        ]
1>C:\Users\jpsie\source\repos\EratosthenesContainer\EratosthenesContainer\EratosthenesHashMap.h(20): message : see reference to class template instantiation 'std::unordered_map<T,unsigned int,boost::hash<T>,std::equal_to<T>,std::allocator<std::pair<const T,unsigned int>>>' being compiled
1>        with
1>        [
1>            T=T
1>        ]

I am trying to create a hashmap as a member variable with key type T, value type unsigned int, and I am using the boost library for a hash function.我正在尝试创建一个 hashmap 作为键类型为 T、值类型为 unsigned int 的成员变量,并且我正在将 boost 库用于 hash function。

The way to define a member of a template class is定义模板 class 成员的方法是

template<class T>
EratosthenesHashMap<T>::EratosthenesHashMap(SieveOfEratosthenes& sieve) 
{
    this->sieve = &sieve;
};

On top of that, you should probably defined the templates in the header file, because otherwise they will only be usable in the same cpp file.最重要的是,您可能应该在 header 文件中定义模板,否则它们将只能在同一个 cpp 文件中使用。

See Why can templates only be implemented in the header file?请参阅为什么模板只能在 header 文件中实现?

It is rather difficult to have a template class split between header file and.cpp file and be easy to consume by callers.在 header 文件和 .cpp 文件之间拆分模板 class 并且易于调用者使用是相当困难的。 Instead, inline your entire template class in EratosthenesHashMap.h :相反,在EratosthenesHashMap.h中内联整个模板 class :

template<class T>
class EratosthenesHashMap
{

public:
    EratosthenesHashMap(SieveOfEratosthenes& sieve)
    {
        this->sieve = &sieve;
    }
    ~EratosthenesHashMap()
    {
    }

    unsigned int addValue(T& value)
    {
        return 0;
    }

    unsigned int getPrime(T& value) const
    {
        return 0;
    }

private:
    SieveOfEratosthenes* sieve;
    std::unordered_map<T, unsigned int, boost::hash<T>> valueMap;
};

The reason your code doesn't compile is that you can't break a class template into ah file and.cpp file in the typical way.您的代码无法编译的原因是您不能以典型的方式将 class 模板分解为 ah 文件和 .cpp 文件。

Say you have a main.cpp file that uses EratosthenesHashMap<int> and you have EratosthenesHashMap broken into ah and a.cpp as in your question, then main.cpp gets compiled completely independently of EratosthenesHashMap.cpp and needs to be able to link to an implementation of EratosthenesHashMap<int> but EratosthenesHashMap.cpp does not know anything about what types it will be applied to so this is impossible.假设您有一个使用EratosthenesHashMap<int>的 main.cpp 文件,并且您在问题中将 EratosthenesHashMap 分解为 ah 和 a.cpp,然后 main.cpp 完全独立于 EratosthenesHashMap.cpp 进行编译,并且需要能够链接到EratosthenesHashMap<int>的实现,但 EratosthenesHashMap.cpp 不知道它将应用于什么类型,所以这是不可能的。

EratosthenesHashMap.cpp does not define a class; EratosthenesHashMap.cpp 没有定义 class; it defines a template;它定义了一个模板; it can't be compiled into an object file that can be linked against.它不能编译成可以链接的 object 文件。

Typically you use templates by providing a full implementation in a header for this reason.出于这个原因,通常您通过在 header 中提供完整实现来使用模板。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM