从 'const char *' 类型的右值初始化 'const char*&' 类型的非常量引用无效

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

我做了一个mystrcpy函数,

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

和一个主要功能:

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;
}

它不编译,并说 "invalid initialization of non-const reference of type 'const char*&' from an rvalue of type 'const char *'"...

当我刚做的时候:

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

它编译没有错误。

我想知道为什么前一个不起作用,谢谢。

"bye bye" 不是指针而是字符数组。它可以衰减为指针,但不能将其作为指针的引用传递。

您可以更改函数签名:

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

如果您想在编译时检查类型,您可以使用静态断言生成编译器错误:

#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++ 给出:

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

您的函数采用对指针的引用,这有点不寻常。值得注意的是,这意味着输入必须是一个指针,它有自己的存储空间(这样你就可以引用指针)。

const char *bye="bye bye"; mystrcpy(hello, bye); 有效是因为 bye 是一个指针变量,所以你可以引用它。

mystrcpy(hello, "bye bye") 失败,因为 "bye bye" 不是 指针 - 它是一个字符数组(const char [8]),因此没有指针做个参考。

您的 mystrcpy 函数签名中不需要引用 & - 这只会使函数更难使用,并且如果您不小心调整了函数中的指针 (例如,如果你开始做 *stuff++ = *other++;).

const char *& 是对 char const * 的非 const 引用。 "bye bye" 的类型是 char const[8](大小包括终止空字符)。您对 mystrcpy 的调用将隐式转换(或 decaychar const [8]char const *,但这会产生一个您无法绑定的右值指针到非 const 参考参数。

如果您将函数签名更改为

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

您的代码将会编译。同样,如果您按值获取指针,您的代码将编译

void mystrcpy(char *, const char *)

修复所有这些问题后,您的代码将编译并可能在运行时崩溃,因为您有未定义的行为。

char *hello="hello";

C++11 禁止您将字符串文字转换为 char *,并且在 C++03 中已弃用该行为。不仅如此,您的 mystrcpy 调用还会尝试覆盖字符串文字,这又是未定义的行为。

调高编译器的警告级别,注意警告。 g++ 对上面带有 -pedantic

的行产生以下警告

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

 char *hello="hello";
             ^