1

I'm having an issue passing unique_ptrs to functions, it seems they go out of scope when I pass to askQuestion.

hears my code.

char askQuestion(string *questions[8], unique_ptr<binaryBase>answered) {
    bool asked = false;
    char input = '0';
    while (!asked) { // loop until you find a question that has not been asked
        int randomQuestion = (rand() % 8); // generate a random number
        if (!(answered->getBit(randomQuestion))) { // check if the question has been answered 
            getInput(input, *questions[randomQuestion]);
            answered->toggleBit(randomQuestion);
            asked = true;
        }
    }
    return input;
}

these two functions access unique_ptrs, function below relies on function above for input. when I call askQuestion I get "(variable) cannot be referenced -- it is a deleted function"


bool checkAnswer(char answer, int place, binaryBase* reference) {
/*  if the answer is T and the correct answer is true, returns true
    if the answer is F and the correct answer is false, returns true
    return false otherwise
*/ return((answer=='T'&&reference->getBit(place))||(answer=='F'&&!reference->getBit(place)));
}

binaryBase is a simple custom class and only has a 8 int as data and getters and setters for bits, this treats the 8 bit int as a byte to store "boolean" answers for the program.

Pat H.
  • 11
  • 4

2 Answers2

2

I'm not seeing a call to askQuestion() in your example. However, I can see that askQuestion() is an "observer" of the answered parameter. A unique_ptr is used to transfer ownership of a pointer, not for just observing it. So you should define that function as:

char askQuestion(string *questions[8], binaryBase& answered)

instead. Use a reference here instead of a pointer to make it clear that passing null is not allowed. (Of course change all occurrences of answered-> to answered.)

When you call that function and want to pass an object managed by a unique_ptr<binaryBase> ptr, then pass the managed object, not the unique_ptr itself with *ptr.

In cases where you actually do want to transfer ownership of the pointer, then you need to move the pointer:

void func(std::unique_ptr<binaryBase>);

// ...
std::unique_ptr<binaryBase> ptr = /* ... */
func(std::move(ptr));

After the call to func(), ptr does not contain an object anymore. func() took ownership of it.

unique_ptr is a "move-only type". It cannot be copied because its copy constructor and copy assignment operator have been deleted, which is the reason of your original compilation error.

Nikos C.
  • 50,738
  • 9
  • 71
  • 96
1
char askQuestion(string *questions[8], unique_ptr<binaryBase>answered)

You are attempting to pass a std::unique_ptr by value to askQuestion() but it's a move-only type. It represents a dynamically allocated object that is not shared by more than one object at a time. You can only move a unique_ptr or pass it by reference. If you intend to pass ownership of the unique pointer then you have to use std::move:

askQuestion(questions, std::move(answered));

where answered is a std::unique_ptr<binaryBase>. Once ownership has transferred to a function then the caller cannot use that unique pointer again.

If you do not want to pass ownership then it can be passed by reference. Change askQuestion() to do that:

 char askQuestion(string *questions[8], unique_ptr<binaryBase> &answered); //non-const lvalue reference

or

char askQuestion(string *questions[8], const unique_ptr<binaryBase> &answered);  //const lvalue reference

When passing by reference the function can use the pointer but not own it, unless you explicitly use std::move within the function with a non-const lvalue reference unique pointer (a const lvalue reference can't be moved).


bool checkAnswer(char answer, int place, binaryBase* reference)

In your code you are passing a pointer to binaryBase to the function checkAnswer(). Again there's no need for this function to own the unique pointer, so you can pass the unique pointer by reference as shown above or use std::unique_ptr's get() method to get a pointer to the object.

You might like to check out this answer, which deals with different ways of passing a unique pointer comprehensively.

jignatius
  • 6,304
  • 2
  • 15
  • 30