从 '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
的调用将隐式转换(或 decay)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
的行产生以下警告
warning: ISO C++ forbids converting a string constant to 'char*' [-Wpedantic]
char *hello="hello";
^
我做了一个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
的调用将隐式转换(或 decay)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
warning: ISO C++ forbids converting a string constant to 'char*' [-Wpedantic]
char *hello="hello"; ^