1

I got a function that accepts a pointer to a rapidjson::Value type and stores the item at that location into a rapidjson::Value of type kArrayType.

void addBlock(rapidjson::Value* block) {
    blocksArray.PushBack(*block, allocator);
}

This function works as expected.

To extend this I want to add a function that can take a vector of these pointers as an input. I tried this doing:

void addBlocks(std::vector<rapidjson::Value*> blocks) {
    for (const rapidjson::Value& block : blocks) {
        blocksArray.PushBack(*block, allocator);
    }
}

This does not work however. It gives me two red waves in Visual Studio.

The first one beneath block in the parameter declaration of the function, saying:

C++ no suitable constructor exists to convert from to...

And the second one beneath the * in the call to PushBack(), saying:

C++ no operator matches these operands operand types are: * const rapidjson::Value

My guess is that I am doing something very basic wrong that I am just missing.

SomeDutchGuy
  • 2,249
  • 4
  • 16
  • 42
  • 2
    `for (const rapidjson::Value& block : blocks) {` -> `for (rapidjson::Value* block : blocks) {` (or `for (rapidjson::Value* const & block : blocks) {`, which is probably what you meant but more verbose for no gain - iterating over pointers by value vs by const ref has the same performance when you just dereference them afterwards). – Max Langhof Nov 29 '19 at 12:32
  • 4
    You can use `auto` keyword to iterate on blocks vector: `for (auto block : blocks) { ...` – lucie Nov 29 '19 at 12:34
  • 2
    Also, when you pass read-only `vector` as argument, you probably want to pass it by const reference, rather than making a copy – Rhathin Nov 29 '19 at 13:08
  • @LucieBoursier could you post that as the solution so I can accept it? – SomeDutchGuy Nov 29 '19 at 14:07

3 Answers3

3

It seems you are doing a copy, so why not use some std algorithm?

void addBlocks(std::vector<rapidjson::Value*> blocks) {
    std::transform(
        blocks.begin(),
        blocks.end(),
        std::back_inserter(blocksArray),
        [](rapidjson::Value* ptr){ return *ptr; });
}
Krzysiek Karbowiak
  • 1,655
  • 1
  • 9
  • 17
1

Your vector contains pointers. Those cannot be automatically converted to references. The loop variable needs to be a reference of a pointer:

for (rapidjson::Value *& block : blocks)
{
     blocksArray.PushBack(*block, allocator);
}

Quite sure this is what "auto" would do under the hood (if the compiler doesn't entirely optimize it away).

Not sure it would allow you to keep the "const". It didn't when I tried this with ints.

AlexGeorg
  • 967
  • 1
  • 7
  • 16
  • 1
    Given you only dereference those pointers, you don't need the reference. `for (rapidjson::Value * block : blocks)` or `for (auto block : blocks)` – Caleth Nov 29 '19 at 14:16
1

You can use auto keyword to iterate on blocks vector:

for (auto block : blocks) { 
   ... 
}
lucie
  • 895
  • 5
  • 19