2

I'm trying to use a library function from VLFeat that calls for data to be a const void *. I don't really understand how to create the data and then pass it in.

This is the function call:

void vl_kmeans_init_centers_with_rand_data  (VlKMeans * self, void const * data,
    vl_size dimension, vl_size numData, vl_size numCenters)

The data argument is the one that throws me. I tried building a random data matrix to test the kmeans clustering function, but I can't figure out how to use the data. In other words, this function requires this argument. But for it to be useful, I have to understand what how to cast/create/load the data to make it work. That means, I need to understand the purpose of the const void * type in the argument.

Any help would be highly appreciated.

Note: I do understand what const means, but, for example, I can't figure out how I can iteratively build const data (i.e. fill a matrix with dual for loops)

Thanks!

marcman
  • 3,233
  • 4
  • 36
  • 71

2 Answers2

12

const, despite the best efforts from the standardization commitee to confuse you, does not mean "constant". It means "read-only".

By declaring its parameter as a pointer-to-const, this function states that your data won't be copied on its way in, but the function's code will only be able to read it, not modify it.

So just build your matrix the regular way (non-const, since you need to complete it with loops), and pass it in, confident that it will return unchanged.

Unless... the function's code casts away the const. Which should get the guy who wrote it fired in no time.

Quentin
  • 62,093
  • 7
  • 131
  • 191
  • `const_cast` -- the bane of our existence. – Billy ONeal Feb 04 '15 at 21:21
  • 2
    @BillyONeal the weapon you unsheathe with a tear, knowing it shouldn't have gone that way. – Quentin Feb 04 '15 at 21:23
  • 1
    @Billy C-style and function style casts are worse, because they can virtually cast *anything* to *anything*. And at least `const_cast` can be found via grep. Try to grep a C-style cast :( – Paul Groke Feb 04 '15 at 21:24
2

The const only means that the vl_kmeans_init_centers_with_rand_data is not allowed to modify that data. I.e. you don't have to use a const array, you can pass a "normal" (mutable) one. const can always be added by an implicit conversion - just not the other way around.

(Allowed to add const: A function may always promise not to modify an object, even it could be modified. Not allowed to remove const: A function may not modify an object, or give it to another function that expects a modifiable object, if the original function has been given the object under the promise that it will not modify the object.)

The void, when used as type for a pointer, means "anything". I.e. you can convert an int-pointer to a void-pointer, a double-pointer to a void-pointer - anything-you-like-pointer to a void-pointer. And the reason for this is, most of the time, that the function taking a void-pointer argument can process different data-types. In this case, VlKMeans has a member dataType which probably controls how the vl_kmeans_init_centers_with_rand_data function will interpret the data argument.

Assuming that e.g. dataType is set to VL_TYPE_DOUBLE, this should work:

std::vector<double> data(numData);
// fill 'data' with data
vl_kmeans_init_centers_with_rand_data(vlkMeans, &data[0], dimension, numData, numCenters);
Paul Groke
  • 6,259
  • 2
  • 31
  • 32