Carl Carl - 1 year ago 68
C++ Question

Map insert results in C2664 error in VS 2015, works in VS 2013

This piece of code was working perfectly in VS 2013 but I had to update to VS 2015 and now it throws an error.

I did read and googled quite a bit however I still have no idea how to fix this.

I'm using eigen math library to do some 3d math stuff. Eigen's Vector3d class cannot be used as a key to containers so I created my own Vector3dLite class to get around this issue.

class Vector3dLite
float VertX, VertY,VertZ;
Vector3dLite(Vector3d& InputVert)
VertX = static_cast<float>(InputVert.x());
VertY = static_cast<float>(InputVert.y());
VertZ = static_cast<float>(InputVert.z());

Vector3dLite(Vector3dLite& InputVert)
VertX = InputVert.VertX;
VertY = InputVert.VertY;
VertZ = InputVert.VertZ;
//more operator overloading stuff below

Here's where compiler throws the error

map<Vector3dLite, int> VertexIds;
int unique_vertid = 0;
VertexIds.insert(make_pair(Vector3dLite(tri.Vert1), unique_vertid)); //This line
// Vert1 is an eigen Vector3d object

Here's the compiler error:

error C2664: cannot convert argument 1 from 'std::pair<Vector3dLite,int>' to 'std::pair<const _Kty,_Ty> &&'
_Alloc=std::allocator<std::pair<const Vector3dLite,int>>

I did try writing const before Vector3dLite object but apparently syntax is not correct.

VertexIds.insert(make_pair(const Vector3dLite(tri.Vert1), unique_vertid));

Answer Source

Since the value type for a map has const object as the first element (the map key), you generally can't use make_pair to construct the value, as the inferred type will not be const.

You can create a pair with explicit types:

std::pair<const Vector3dLite, int>(Vector3dLite(tri.Vert1), unique_vertid)

You can use the map's type

std::map<Vector3dLite, int>::value_type(Vector3dLite(tri.Vert1), unique_vertid)

Or you can create a named const object to use is make_pair

const Vector3dLite mapkey(tri.Vert1);
make_pair(mapkey, unique_vertid);

One other note: Your constructors should take their parameters by const &.