1

I'm trying to use the std::map's [] operator with a custom key type:

typedef tuple<DWORD, DWORD, DWORD, DWORD> Version; // Key type

const map<Version, string> codenames {
    { {3,0,1,5}, "Maserati" },
    { {3,0,2,6}, "Elephant" }
};

Version ver{3,0,2,6};
string codename = codenames[ver];
// Error C2678 binary '[': no operator found which takes a left-hand operand of type '...' (or there is no acceptable conversion)

string codename = codenames[{3,0,2,6}];
// Same error

Is it possible to access the values using the [] operator with that custom key type? I'm using Visual Studio 2015 Update 3.

PS:

The question: std::maps with user-defined types as key is not a duplicate, because it's not related to the [] operator and doesn't answer this question.

Community
  • 1
  • 1
karliwson
  • 3,365
  • 1
  • 24
  • 46
  • In order to use the `[]` operator with a custom key type, you need to do two things: (1) define a map with your custom key type, which is fully explained in the linked question, and (2) use the `[]` operator. Which of the two steps you're stuck at? Do you expect you should be able to do (2) without doing (1)? – n. m. could be an AI Jan 15 '17 at 07:36
  • @n.m. '(1) define a map with your custom key type' didn't I do it in my example? – karliwson Jan 15 '17 at 07:40
  • @n.m. You forgot step 0: make sure your key type supports required operations (which tuple does). Incidentally, OP code works for me: http://coliru.stacked-crooked.com/a/c9c18005e93179b1 – Revolver_Ocelot Jan 15 '17 at 07:44
  • The online tool uses clang++. I use Visual Studio, which fails to compile it, but unfortunately I have to use it. Still trying to find a solution. – karliwson Jan 15 '17 at 07:46
  • I feel the linked Qn is a good duplicate. How about [this Qn](http://stackoverflow.com/q/906244/514235) or [this Qn](http://stackoverflow.com/q/31839913/514235). Do they answer your query? If not then it will be good if you can be more specific in your post by putting some extra info. – iammilind Jan 15 '17 at 07:48
  • It's clear now that it's a compiler-related problem. GCC and Clang can compile it, but not Visual Studio 2015 Update 3 (c++ 17). – karliwson Jan 15 '17 at 07:56
  • 3
    I'm not sure it's compiler related. Your program can be made to compile in VC++ http://rextester.com/THWESQ23006 – StoryTeller - Unslander Monica Jan 15 '17 at 08:02
  • VS2015 works fine too: http://rextester.com/BLTB18616 – Revolver_Ocelot Jan 15 '17 at 08:02
  • The compilation error found in the linked answer is not Visual Studio-specific and can be reproduced with any compiler. It is absolutely trivial to fix. – n. m. could be an AI Jan 15 '17 at 08:04
  • 1
    Are you sure your report of the problem is accurate? Your map definition is invalid (since std::tuple constructors are explicit). – StoryTeller - Unslander Monica Jan 15 '17 at 08:05
  • @Potatoswatter - Is that so? That's exactly what VC++ choked on in the online code pad I linked to. Another point to chalk against Microsoft's compiler writers. – StoryTeller - Unslander Monica Jan 15 '17 at 08:11
  • @Potatoswatter - And clang's writers as well apparently, since they accept copy initialization http://coliru.stacked-crooked.com/a/201f52db905f4796 – StoryTeller - Unslander Monica Jan 15 '17 at 08:12
  • @Potatoswatter which compiler compiles it? – n. m. could be an AI Jan 15 '17 at 08:14
  • 2
    The actual problem was that I simplified my code so I could show it in the question, and I forgot to add a `const` modifier to the map. When the `codenames` map is a `const`, the compilation fails with the error I've mentioned before. I'm not sure why. Also, I don't know if I should post an answer explaining that. – karliwson Jan 15 '17 at 08:25
  • 3
    @karliwson operator[] does not work on constant maps, use `.at()` instead. – Revolver_Ocelot Jan 15 '17 at 08:26
  • 1
    As @Revolver_Ocelot points out. You omission was the cause of all your symptoms. – StoryTeller - Unslander Monica Jan 15 '17 at 08:28
  • 1
    @StoryTeller Woops, I was wrong about that. The rule is to always use copy-initialization, i.e. an implicit `=`. (N4618 §8.6.1/3, 8.6.4/5. Same in C++14.) So MSVC is right; Clang and GCC are wrong. – Potatoswatter Jan 15 '17 at 08:28
  • @StoryTeller you're right. I never suspected that it was the cause. – karliwson Jan 15 '17 at 08:35

0 Answers0