简体   繁体   中英

invalid initialization of non-const reference of type 'const char*&' from an rvalue of type 'const char *'

i made a mystrcpy function,

void mystrcpy(char *&stuff, const char *&otherstuff){
    for(int i=0; stuff[i]&&other[i]; i++){
        stuff[i]=other[i];
    }
}

and a main function:

int main(){
    char *hello="hello";
    mystrcpy(hello, "bye bye"/*<--i have no clue what data type this really is!!*/);
    printf("%s\n", hello);
    return 0;
}

it does not compile, and says "invalid initialization of non-const reference of type 'const char*&' from an rvalue of type 'const char *'"...

when i just do:

const char *bye="bye bye";
mystrcpy(hello, bye);

it compiles without error.

i need to know why the former one doesnt work, thanks.

"bye bye" is no pointer but an array of characters. It can decay to a pointer, but it is not possible to pass it as a reference to a pointer.

You might change the function signature:

void mystrcpy(char *stuff, const char *otherstuff)

If you want to inspect a type at compile time, you might use a static assertion generating a compiler error:

#include <type_traits>

template <typename T>
void inspect_type(T&)
{
    static_assert(std::is_same<T, void>::value, "inspect_type");
}

int main()
{
    inspect_type("bye bye");
}

g++ gives:

In instantiation of 'void inspect_type(const T&) [with T = const char [8]]' ...

const char *& is a non- const reference to a char const * . The type of "bye bye" is char const[8] (the size includes the terminating null character). Your call to mystrcpy will implicit convert (or decay ) the char const [8] to a char const * , but that produces an rvalue pointer, which you cannot bind to a non- const reference parameter.

If you change your function signature to

void mystrcpy(char *&, const char * const&)
//                                  ^^^^^ const reference

your code will compile. Similarly, if you take the pointer(s) by value, your code will compile

void mystrcpy(char *, const char *)

Once you fix all that, your code will compile and probably crash at runtime, because you have undefined behavior.

char *hello="hello";

C++11 forbids you from converting a string literal to a char * , and it was deprecated behavior in C++03. Not only that, but your mystrcpy call then attempts to overwrite the string literal, which is again undefined behavior.

Turn up your compiler's warning level, and pay attention to the warnings. g++ produces the following warning for the line above with -pedantic

warning: ISO C++ forbids converting a string constant to 'char*' [-Wpedantic]

  char *hello="hello"; ^ 

Your function takes a reference to a pointer , which is a bit unusual. Notably, this means that the input must be a pointer that has its own storage (so that you can take a reference to the pointer).

const char *bye="bye bye"; mystrcpy(hello, bye); works because bye is a pointer variable, so you can take a reference to it.

mystrcpy(hello, "bye bye") fails because "bye bye" is not a pointer - it's an array of characters (a const char [8] ) and so there's no pointer to take a reference to.

You do not need the reference & in your mystrcpy function signature - that simply makes the function harder to use, and can introduce interesting bugs if you accidentally adjust the pointers in the function (eg if you started doing *stuff++ = *other++; ).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM