函数调用带有指针、引用和常量引用参数的歧义
function call ambiguity with pointer, reference and constant reference parameter
我想做的是,允许使用setter函数传递指针,引用或常量引用:
class A{
std::string * p;
std::string st;
public:
A():p(0)
{}
A& setS(const std::string& s){
std::cout<<"called with const std::string&n";
st = s;
p = &st;
return *this;
}
A& setS(std::string& s) {
std::cout<<"called with std::string&n";
p = &s;
return *this;
}
A& setS(std::string* s) {
std::cout<<"called with std::string*n";
p = s;
return *this;
}
};
int main(){
std::string s;
A a;
a.setS(std::move(s)) //const std::string&
.setS("") //const std::string&
.setS(s) //std::string&
.setS(0); //std::string*
//if std::string* version is not defined,
//setS(0) calls the const std::string& version and throws exception
return 0;
}
但是我已经看到,如果指针版本不存在,setS(0)
调用setS()
函数的const std::string&
版本。
指针和参考版本之间或任何其他重要版本之间是否存在任何歧义? 它是否定义良好,并期望在所有编译器中以相同的方式工作?
没有歧义。 当重载集中有A& setS(std::string* s)
时,setS(0)
调用指针版本,0
是空指针。 这将是setS(nullptr)
的等价物.
当A& setS(std::string* s)
不在重载集中时,编译器会查看是否有办法从0
构造临时字符串,然后将其传递给A& setS(const std::string& s)
因为const&
可以绑定到临时字符串。std::string
可以从单个指针构造,并再次0
它作为空指针进行。 因此,你会得到一个构造std::string
传递给const&
函数的临时空指针。
不过,这是未定义的行为。std::string
的构造函数要求传递给它的指针是以 null 结尾的 c 字符串。 如果不是,则行为未定义。
删除setS
函数的指针重载时,调用const std::string&
版本的原因是std::string
构造函数之一。
basic_string( const CharT* s,
const Allocator& alloc = Allocator() );
所以0
被当作NULL
,并被解释为一个const char*
,从中可以构造一个std::string
。const&
能够延长左值的寿命,因此它可以传递到setS
的重载中。
相关文章:
- 什么时候在C++中返回常量引用是个好主意
- 我想将一个对T类型的非常量左值引用绑定到一个T类型的临时值
- 为什么我可以通过引用修改常量返回
- 返回常量对象引用 (getter) 和仅返回字符串有什么区别?
- 将常量指针引用绑定到非常量指针
- 通过常量引用传递参数的矩阵模板类
- 按值捕获引用时出现非常量
- 在C++中使用非常量引用作为常量
- 具有常量引用参数的函数模板专用化
- 多个"常量引用"变量可以共享同一个内存吗?
- 为什么 STL 容器适配器堆栈中的 top 返回常量引用?
- 为什么按值传递QStringView比引用常量更快?
- 通过引用常量函数调用另一个类的非常量函数
- 构造常量对象与引用常量对象
- 引用“常量value_type”时出错
- 为什么可以在 for 语句中重新分配引用常量
- 程序反馈:命名循环索引和引用常量数据
- 堆还是栈?在c++中函数调用中引用常量字符串时
- 为什么常量结构数组在按名称引用常量结构时不放在 .rodata 中?
- 为什么编译器允许在函数中发送对迭代器的引用,该函数引用常量迭代器