1

I'm trying to manually port some Java into C++.

The Java:

public Class Item {
    public String storage = "";
    public Item(String s, int tag) { storage = s; }
    ...
}

public class ProcessItems {
    Hashtable groups = new Hashtable();
    void save(Item w) { groups.put(w.storage, w); }
}

My C++:

#include<iostream>
#include<unordered_map>
#include<string>


class Item {
    public:
        std::string storage;
        Item(std::string s, int tag) { storage = s; }
        ...
}

class ProcessItems {
    public:
        std::unordered_map<std::string, std::string> *groups = new std::unordered_map<std::string, std::string>();
        void save(Item w) { groups.insert(w::storage, w); }
        ...
}

Compiling in C++ 11 I get the following error:

error: invalid use of ‘::’
    string, std::string> *words = new std::unordered_map<std::string, std::string>();
                                                                         ^

Where'd I go wrong?

OrdinaryHuman
  • 621
  • 11
  • 19
  • 3
    I strongly suggest getting rid of the pointer. It's far more common and less work to have `std::unordered_map<...> groups;` and leave it at that. For example, I'll bet you don't have a [destructor, copy constructor, and assignment operator](http://stackoverflow.com/questions/4172722/what-is-the-rule-of-three) to avoid the pointer being invalid or the map leaked. It's much easier to have a plain object that gets destroyed when the class does and gets copied when the class does. – chris Oct 06 '17 at 12:52
  • Having pointers to containers (vectors, maps, etc) is an anti-pattern. A common reason is that you want to have a `nullptr` if there are no elements, but in that case you should have an empty container. – MSalters Oct 06 '17 at 12:57
  • As a straight port, this will work, but once you get it working you'll want to un-pointer all of your code, as everyone else has said. It prevents null pointer issues and makes your data more spatially local. – Silvio Mayolo Oct 06 '17 at 12:59
  • @FrançoisAndrieux: [why not?](http://hc.apache.org/httpcomponents-client-ga/tutorial/html/authentication.html) – MSalters Oct 06 '17 at 12:59
  • There needs to be `;` at the end of each class definition. In any event, avoid making members pointers, which also means don't create objects using operator `new`. C++ differs substantially from Java in this regard - writing as you would in Java is VERY poor practice in C++. – Peter Oct 06 '17 at 13:16

1 Answers1

11

In Java both member resolution and scope resolution are done with operator dot ., while in C++ these operators are different:

  • Use :: to access a member of a namespace or a static member of a class
  • Use . to access a member of an instance represented by reference or by value
  • Use -> to access a member of an instance represented by pointer

Since storage is an instance member of Item, use

groups.insert(w.storage, w);

Note that you would be better off if you pass w by constant reference:

void save(const Item& w) { groups.insert(w::storage, w); }

You also need to change groups from a pointer to an object, and fix its type to match what you plan to put into the map:

std::unordered_map<std::string,Item> groups;

Unlike Java, C++ will initialize groups to a valid object without an explicit call to the default constructor.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523