4

I'm just playing with new VS 2012 and I have a problem probably with new C++11. This pease of code work perfectly when I set platform toolset to VS2010 (v100) in project settings.

.h:

typedef std::multimap<unsigned, unsigned>   SizeMap;
typedef std::map<unsigned, unsigned>        OffsetMap;

private:
    inline void _RemoveBlockL(SizeMap::iterator sizeI);
    inline void _RemoveBlockL(OffsetMap::iterator offsetI);

.cpp:

inline void Foo::_RemoveBlockL(SizeMap::iterator sizeI)
{
// impementation
}

inline void Foo::_RemoveBlockL(OffsetMap::iterator offsetI)
{
// impementation
}

But when I change that for VS2012 (v110), I'll get these error:

Error   61  error C2535: 'void
Boo::system::Foo::_RemoveBlockL(std::_Tree_iterator<_Mytree>)' : member function already
defined or declared D:\_work\wp-test\boo\system\foo.h

Why is overloading not working in VC++11?

Lipov3cz3k
  • 454
  • 4
  • 14

2 Answers2

5

It's just a possibility, I can't check at the moment, but they changed the way iterators are implemented in vc++11 so it's possible they are the same underlying type making it impossible to overload on it.

Is it required that iterators to different container types have different types themselves?

See this http://blogs.msdn.com/b/vcblog/archive/2012/04/06/10291485.aspx

jcoder
  • 29,554
  • 19
  • 87
  • 130
  • They are allowed to be independent of the value type (and other template parameters), but I'm not sure they are also allowed to be independent of the actual container type. But this sounds like a reasonable explanation. – Christian Rau Sep 06 '12 at 14:32
  • A number of implementations use raw pointers for iterators in a `vector` (with a simple typedef), so even if now allowed, it's used. – Matthieu M. Sep 06 '12 at 14:36
  • Given the very generic iterator type from the error message, this seems likely. – Mark Ransom Sep 06 '12 at 16:47
  • It's definitely allowed. The `iterator` typedefs are all specified as being implementation-defined. The implementation is free to define them however it sees fit. – James McNellis Sep 24 '12 at 21:07
1

The two possibilities I can think of are that since _RemoveBlockL is reserved for the compiler, something changed and it's now reserved, or that in the new compiler the two iterators actually alias the same type. Do you actually need different functional behavior depending on whether it's a map or multimap?

Assuming you do (because of the typedef names), the correct solution is to just not use overloading to solve this problem. Give the functions names that represent what they actually do (or alternately you may be able to use strong_typedef to make a strong alias so you can overload but I can't visualize the full solution).

Mark B
  • 95,107
  • 10
  • 109
  • 188
  • I renamed those two functions and it seems to works. Thank you! – Lipov3cz3k Sep 07 '12 at 08:08
  • @Lipov3cz3k Did you rename both functions to the same name? If not, then it's much more likely that the answer's second possibility is the correct explanation, which is totally equivalent to *J99*'s much earlier answer. – Christian Rau Sep 07 '12 at 09:04
  • I renamed with different names. If I try to rename both functions to the same name (not reserved), I've get the same error. So _J99's_ explanation is probably right - they changed something with iterators and now is the signature of both functions same, IMO – Lipov3cz3k Sep 07 '12 at 12:27