tags:

views:

126

answers:

5

I'm declaring a map of string to a pair of pairs as follow:

std::map<std::wstring, 
         std::pair<std::pair<long, long>, 
                   std::pair<long, long>>> reference;

And I initialize it as:

reference.insert(L"First", 
                 std::pair<std::pair<long, long>, 
                           std::pair<long, long>>(std::pair<long, long>(-1, -1),
                           std::pair<long, long>(0, 0)));

However, Visual C++ gives me the error "C2664, No constructor could take the source type, or constructor overload resolution was ambiguous".

I'm new to using templates and STL and I can't tell what I'm doing wrong.

+10  A: 

The >>> can not be parsed correctly (unless you have a C++0x compiler).

Change to > > >

This:

reference.insert("First",

Should be:

reference.insert(L"First",
                ^^^

Also there is a utility function to make the construction of pairs easier:

std::pair<std::pair<long, long>, std::pair<long, long>>(std::pair<long, long>(-1, -1), std::pair<long, long>(0, 0))

Can be:

std::make_pair(std::make_pair(-1L,-1L),std::make_pair(0L,0L))

Try this:

reference[L"First"]
    = std::make_pair(std::make_pair(-1L,-1L),std::make_pair(0L,0L));
Martin York
Thanks for the help. I edited my question to add the L"" to my wstring to make the question more easier to "parse".
Fábio
A better answer than mine, but note that inserting with `reference[key] = value` can give different behaviour to `reference.insert(make_pair(key,value))`; using `[]` will overwrite an existing element, while `insert` won't.
Mike Seymour
+2  A: 

C++ gets confused by the consecutive ">" when you close the template as it interprets that as the shift operator.

Add spaces between the closing templates, change >>> to > > >

iniju
Also, GMan's advice.
iniju
+2  A: 

map::insert itself takes a single std::pair argument, rather than two arguments. You can tidy up the code by using std::make_pair (which infers the template arguments from the function arguments), to get something like:

reference.insert(std::make_pair("First", 
                                std::make_pair(std::make_pair(-1L,-1L),
                                               std::make_pair(0L,0L))));
Mike Seymour
A: 

It helps to use typedefs when debugging this sort of thing.

// test1.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include <map>
#include <string>

int _tmain(int argc, _TCHAR* argv[])
{
    typedef std::pair<long, long> ElementType;
    typedef std::pair<ElementType, ElementType> ValueType;
    typedef std::wstring KeyType;
    std::map<KeyType, ValueType> reference;

    KeyType key = L"First";
    reference[key] = ValueType(ElementType(-1, -1), ElementType(0, 0));

    return 0;
}
ttt
There is not such `insert()` function as the OP tries to use, even if you `#include <string>`. The sample code you posted works and is quite readable, but because you replaced the `insert()`, not because of the include as you seem to say...
sth
@ttt: If you remove the "you just need `<string>`" part, which I think is somewhat misleading, I would think it *is* helpful and would upvote it.
sth
ok, you got it. I don't know if you realise you wrote "operator[] for insertion results in easier to read code" in your answer. As you say, insert doesn't exist!
ttt
Yeah I realize that and I saw your answer after posting mine and thought "who has downvoted this, operator[] is the way to go!". Then I got confused by the `<string>` stuff and went off to try if maybe actually some missing constructor for `wstring(const char*)` or such would produce an error message like in the question. I couldn't reproduce anything like that, though, so I decided to comment. (+1)
sth
A: 

You could simplify your code by creating a helper function to create pairs of pairs, analog to the std::make_pair helper function that is available in the standard library. Also using the maps operator[] for insertion results in easier to read code:

template<typename T, typename U, typename V, typename W>
std::pair< std::pair<T,U>, std::pair<V,W> > make_pair_pair(T t, U u, V v, W w) {
   // using std::make_pair instead of the constructor for better readability
   return std::make_pair(std::make_pair(t, u), std::make_pair(v, w));
}

reference[L"First"] = make_pair_pair(1,2,3,4);
sth