成本字符*类型的非常量引用的无效初始化,并且来自常量字符*类型的临时引用
invalid initialization of non-const reference of type cost char*& from a temporary of type const char*
编译以下程序后,我收到此错误:
char const* func(char const* a, char const* b)
{
return std::strcmp(a,b)<0?b:a;
}
char const*& func(char const*& a, char const*& b,char const*& c)
{
return func(func(a,b),c);
}
int main()
{
const char* a="First";
const char* b="Second";
const char* c="Third";
func(func(a,b),c); //ERROR
return 0;
}
问题:
1.由于func(a,b(返回值而抛出错误,但我不知道原因。
2.为什么从函数返回时创建临时(字符常量*,字符康斯特*(?它是否因为调用方没有变量来收集返回值而创建?
编辑:此错误已在其他线程中讨论过,但在这种情况下,情况不同(尽管希望原因必须相同(,因此我问了这个问题,因为在这种情况下解释并不明显。请不要将其标记为重复。
起初我误判了你的问题,因为我误读了你的代码。实际上,在您的代码中,char const*& func(char const*& a, char const*& b,char const*& c)
永远不会被称为;)
这部分代码实际上可以正常工作:
#include<cstring>
char const* func(char const* a, char const* b)
{
return std::strcmp(a, b)<0 ? b : a;
}
#include<iostream>
int main()
{
const char* a = "First";
const char* b = "Second";
const char* c = "Third";
std::cout << func(func(a, b), c) << std::endl;
std::cin.ignore();
return 0;
}
返回"第三">
当您将 main 中的func(func(a, b), c)
更改为func(a, b, c)
时,就会出现问题。这是因为您将指针与对指针的引用相结合。这是可以做到的,但不是你这样做的方式。
现在,如果您调用func(a, b, c)
,则所有参数都通过引用传递给第二个函数。为了演示这意味着什么,请考虑以下代码:
#include<iostream>
int main()
{
const char* a = "First";
std::cout << "a: " << (void*)a << ", &a:" << &a << std::endl;
const char* b = "Second";
std::cout << "b: " << (void*)b << ", &b:" << &b << std::endl;
const char* c = "Third";
std::cout << "c: " << (void*)c << ", &c:" << &c << std::endl;
std::cin.ignore();
return 0;
}
对我来说,这返回:
a: 00938B30, &a:00B9FEEC
b: 00938BE4, &b:00B9FEE0
c: 00938BF4, &c:00B9FED4
看?a
是一个包含地址的指针,但也有一个指向a
!的地址。当您通过引用调用时,将传递这些内容。
但是,在此(第二个func
(函数中,调用复制指针值的第一个func
,因为它不是通过引用传递参数。这些本地副本是临时值,一旦函数超出范围,它们就会被销毁。问题是第二个(func
(函数试图将此本地副本的地址写入引用调用的值。
好吧,我不知道你是否在这里跟着我。让我们通过一个例子来演示内存中发生的事情:
#include<cstring>
#include<iostream>
char const* func(char const* const a, char const* const b)
{
std::cout << "Func1:n";
std::cout << "local: a: " << (void*)a << "<--copy, &a:" << &a << "<--*different from main!*n";
std::cout << "local: b: " << (void*)b << "<--copy, &b:" << &b << "<--*different from main!*n";
return std::strcmp(a, b)<0 ? b : a;
}
char const*& func(char const*& a, char const*& b, char const*& c)
{
std::cout << "Func2:n";
std::cout << "ref: a: " << (void*)a << "<--original, &a:" << &a << "<--originaln";
std::cout << "ref: b: " << (void*)b << "<--original, &b:" << &b << "<--originaln";
std::cout << "ref: c: " << (void*)c << "<--original, &c:" << &c << "<--originaln";
char const* const out = func(func(a, b), c);
std::cout << "Func2:n";
std::cout << "local: out: " << (void*)out << ", &out:" << &out << " (cannot return this local variable to a reference)n";
return c; // just to fix it for now
}
int main()
{
std::cout << "Main:n";
const char* a = "First";
std::cout << "a: " << (void*)a << ", &a:" << &a << "n";
const char* b = "Second";
std::cout << "b: " << (void*)b << ", &b:" << &b << "n";
const char* c = "Third";
std::cout << "c: " << (void*)c << ", &c:" << &c << "n";
func(a, b, c);
std::cin.ignore();
return 0;
}
对我来说,这返回:
Main:
a: 00F38D00, &a:005EF78C
b: 00F38C00, &b:005EF780
c: 00F38D08, &c:005EF774
Func2:
ref: a: 00F38D00<--original, &a:005EF78C<--original
ref: b: 00F38C00<--original, &b:005EF780<--original
ref: c: 00F38D08<--original, &c:005EF774<--original
Func1:
local: a: 00F38D00<--copy, &a:005EF5A4<--*different from main!*
local: b: 00F38C00<--copy, &b:005EF5A8<--*different from main!*
Func1:
local: a: 00F38C00<--copy, &a:005EF5A8<--*different from main!*
local: b: 00F38D08<--copy, &b:005EF5AC<--*different from main!*
Func2:
local: out: 00F38D08, &out:005EF680 (cannot return this local variable to a reference)
现场演示
我希望这对你来说足够清楚
相关文章:
- 如何为具有常量类型的函数正确转换来自 DLsym 的返回值?
- 常量和非常量类型的相同模板专用化
- 另一个:从"常量类型*"到"类型*"的转换无效
- 派生类中函数参数变化的虚函数按常量类型在"function parameter"会破坏虚拟机制吗?
- 模板和常量类型
- 返回对常量指针的引用,指向常量类型
- 错误:常量类型为c++的单元化成员
- 如何在不重复函数的情况下推导出常量和非常量类型
- JUCE - 成员函数不可行:'this'参数具有常量类型
- 未找到采用常量类型的左操作数的'=='运算符
- 重载全常量类型的复制赋值运算符的正确方法是什么?
- 忽略候选模板:无法将"常量类型参数-0-0 *"与"字符"匹配
- C++中的部分常量类型转换
- 常量类型之间的区别
- 提升::任何构造函数 - 常量类型重载分辨率
- 如何声明模板常量类型
- 编译时生成的常量类型 ID
- 转换为常量类型,初始化数组
- 正在获取模板中的非常量类型
- 如何使用元编程过滤常量类型和非常量类型