类型' const char *&'的非const引用的无效初始化来自类型' const char *'的右值

时间:2015-07-14 16:19:40

标签: c++ reference const reference-binding

我做了一个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;
}

它没有编译,并且说&#34;类型&#39; const char *&amp;&#39;的非const引用的无效初始化来自类型&#39; const char *&#39;&#34; ...

的右值

当我这样做时:

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

它编译没有错误。

我需要知道为什么前者不起作用,谢谢。

3 个答案:

答案 0 :(得分:2)

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

  

实例化'void inspect_type(const T&amp;)[with T = const char [8]]'   ...

答案 1 :(得分:2)

const char *&是对const的非char const *引用。 "bye bye"的类型为char const[8](大小包括终止空字符)。您对mystrcpy的调用将隐式转换(或衰减char 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

为上面的行生成以下警告
  

警告:ISO C ++禁止将字符串常量转换为&#39; char *&#39; [-Wpedantic]

 char *hello="hello";
             ^

答案 2 :(得分:1)

你的函数需要对指针的引用,这有点不寻常。值得注意的是,这意味着输入必须是具有自己存储的指针(以便您可以引用指针)。

const char *bye="bye bye"; mystrcpy(hello, bye);有效,因为bye是指针变量,因此您可以对其进行引用。

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

您的&函数签名中不需要引用mystrcpy - 这只会使函数更难使用,如果您不小心调整函数中的指针,可能会引入有趣的错误(例如,你开始做*stuff++ = *other++;)。