Nick
Nick

Reputation: 19664

unordered_map - Implicit instantiation of undefined template

My C++ is rusty. I have a member variable that is a unordered_map<some_enum_type, string>.

I am trying to populate the map in the class constructor. What am I doing wrong here?

From the my header:

#include <iostream>
#include <unordered_map>

using namespace std;

typedef enum{
    GET,
    POST,
    PUT,
    DELETE
}http_verb;

class CouchServer{
    string host;
    int port;
    string dbname;
    unordered_map<http_verb,string> req_types;
public:

My constructor implementation:

 CouchServer::CouchServer(string host, int port, string dbname){
    this->host = host;
    this->port = port;
    this->dbname = dbname;
    this->req_types = {
        {req_types[GET], "GET"},
        {req_types[POST], "POST"},
        {req_types[PUT], "PUT"},
        {req_types[DELETE],"DELETE" }
    };
   }

Update:

After reading the provided answers and comments I have changed my header to look like:

    class CouchServer{
    string host;
    int port;
    string dbname;
    unordered_map<http_verb,string> req_types;
public:
    CouchServer(std::string host, int port, std::string dbname)
    : host(std::move(host))
    , port(port)
    , dbname(std::move(dbname))
    , req_types{
        { http_verb::GET, "GET" },
        { http_verb::POST, "POST" },
        { http_verb::PUT, "PUT" },
        { http_verb::DELETE, "DELETE" }
    }
    {  }

The same issue persists. I should mention I am trying to compile this code using XCode 4, that is to say Apple LLVM compiler 4.2.

Upvotes: 1

Views: 2608

Answers (1)

Kerrek SB
Kerrek SB

Reputation: 477060

That might be a compiler limitation. Something similar works for me in GCC 4.7.2, and the standard does indeed say that there's an assignment operator that takes an initializer list.

But you shouldn't be doing any assignment in a constructor! Much better to use the constructor-initializer list:

CouchServer(std::string host, int port, std::string dbname)
: host(std::move(host))
, port(port)
, dbname(std::move(dbname))
, req_types { { http_verb::GET, "GET" } }  // etc.
{  }

(And of course never, ever, ever say abusing namespace std; in a header file.)

You'll have to specialize std::hash for your enum; casting to a suitable integral type should do the trick.

Upvotes: 2

Related Questions