1

I am trying to solve this question where I have to spell numbers.
When I try to call my array of strings a by reference, I get this error. But I get no error if I call it by value.
I don't know where is the rvalue coming from as my string elements should be considered lvalue.

#include <iostream>
#include <string>
using namespace std;

void spell(int n,string* &a){
    if(n==0)
    return;
    spell(n/10,a);
    cout<<a[n%10];
}
int main(){
    int n;
    cin>>n;
    string a[10]{"zero ","one ","two ","three ","four ","five ","six ","seven ","eight ","nine "};
    spell(n,a);
    if(n<0)
    return 0;
    return main();
}
anonymous38653
  • 393
  • 4
  • 16
  • Why do you have *& you are not changing what a is pointing to within that function. – Omid CompSCI Apr 29 '20 at 22:01
  • Unrelated: Rethink `return main();`. I'm not sure what you meant to do here, but calling `main` is illegal. – user4581301 Apr 29 '20 at 22:02
  • @OmidCompSCI I was thinking that if the question wanted me to do it for many many integers at once, performing string copy many many times would slow it down – anonymous38653 Apr 29 '20 at 22:12
  • @AjayTyagiB18ME003, if you pass just a * you are not passing a copy, so there is no overhead there – Omid CompSCI Apr 29 '20 at 22:13
  • @user4581301 I don't know why is it illegal, but I do it everytime when I test my code . I keep giving the inputs, and main repeats until I enter some invalid input ( in this case, negative values) – anonymous38653 Apr 29 '20 at 22:14
  • @OmidCompSCI Yes, that's right. I don't know why I was thinking of string copies being made – anonymous38653 Apr 29 '20 at 22:15
  • @AjayTyagiB18ME003 "*I do it everytime when I test my code*" - well, stop doing it. It is *illegal*. Use an ordinary loop instead. – Remy Lebeau Apr 29 '20 at 22:16
  • @RemyLebeau Alright, I'll start using loop instead. btw I was waiting to get an error someday. – anonymous38653 Apr 29 '20 at 22:24
  • [What the C++ Standard has to say about calling `main`](https://timsong-cpp.github.io/cppwp/basic#start.main-3) – user4581301 Apr 29 '20 at 22:33

1 Answers1

5

First off, calling main() is illegal, so return main(); is undefined behavior. Use a do..while loop instead if you want to run main()'s code multiple times.

The rvalue the compile is complaining about comes when the string[] array decays into a string* pointer to the 1st element when passed to spell(). Your declaration of a is a non-const lvalue reference, which cannot be bound to an rvalue, hence the compiler error.

spell() does not modify a itself to point somewhere else, it is only accessing the string objects in the array that a points to, so there is no need to pass a by reference, passing it by value will work just fine:

void spell(int n, string* a)

Live Demo

Or, passing it by const reference will also work, since a const lvalue reference can be bound to an rvalue:

void spell(int n, string* const &a)

Live Demo

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770