admin管理员组文章数量:1123152
The following piece of code compiles fine
#include <iostream>
#include <map>
#include <memory>
using namespace std;
class child {
public:
child(std::string name,uint32_t age) : name(name),age(age){
}
std::string name;
uint32_t age;
};
class parent {
public:
uint32_t age;
parent(std::string name){
age = 10;
}
std::map<uint32_t, std::shared_ptr<child>> child_by_age;
std::map<std::string, std::shared_ptr<child>> child_by_name;
child& operator[](const uint32_t& num){
return *(child_by_age[num]);
}
child& operator[](const std::string& n){
return *(child_by_name[n]);
}
void addChild(const child& ch){
auto ch_obj = std::make_shared<child>(ch);
child_by_age.emplace(ch.age, ch_obj);
child_by_name.emplace(ch.name, ch_obj);
}
};
class top {
public:
parent p1;
top():p1("p1"){
p1.addChild(child("c0",0));
p1.addChild(child("c1",1));
}
void run(){
p1["c0"].name = "name";
p1[0].name = "name1";
}
};
int main(){
top t;
t.run();
return 0;
}
But the moment I add following conversion operator
operator uint32_t() const{
return age;
}
I am getting the following error
operator_overload.cpp: In member function ‘void top::run()’:
operator_overload.cpp:50:11: error: ambiguous overload for ‘operator[]’ (operand types are ‘parent’ and ‘const char [3]’)
p1["c0"].name = "name";
^
operator_overload.cpp:50:11: note: candidate: operator[](long int, const char*) <built-in>
operator_overload.cpp:28:12: note: candidate: child& parent::operator[](const string&)
child& operator[](const std::string& n){
^~~~~~~~
I am not sure to understand why the compiler complains on subscript operator when I add conversion operator
The following piece of code compiles fine
#include <iostream>
#include <map>
#include <memory>
using namespace std;
class child {
public:
child(std::string name,uint32_t age) : name(name),age(age){
}
std::string name;
uint32_t age;
};
class parent {
public:
uint32_t age;
parent(std::string name){
age = 10;
}
std::map<uint32_t, std::shared_ptr<child>> child_by_age;
std::map<std::string, std::shared_ptr<child>> child_by_name;
child& operator[](const uint32_t& num){
return *(child_by_age[num]);
}
child& operator[](const std::string& n){
return *(child_by_name[n]);
}
void addChild(const child& ch){
auto ch_obj = std::make_shared<child>(ch);
child_by_age.emplace(ch.age, ch_obj);
child_by_name.emplace(ch.name, ch_obj);
}
};
class top {
public:
parent p1;
top():p1("p1"){
p1.addChild(child("c0",0));
p1.addChild(child("c1",1));
}
void run(){
p1["c0"].name = "name";
p1[0].name = "name1";
}
};
int main(){
top t;
t.run();
return 0;
}
But the moment I add following conversion operator
operator uint32_t() const{
return age;
}
I am getting the following error
operator_overload.cpp: In member function ‘void top::run()’:
operator_overload.cpp:50:11: error: ambiguous overload for ‘operator[]’ (operand types are ‘parent’ and ‘const char [3]’)
p1["c0"].name = "name";
^
operator_overload.cpp:50:11: note: candidate: operator[](long int, const char*) <built-in>
operator_overload.cpp:28:12: note: candidate: child& parent::operator[](const string&)
child& operator[](const std::string& n){
^~~~~~~~
I am not sure to understand why the compiler complains on subscript operator when I add conversion operator
Share Improve this question edited 6 hours ago Yksisarvinen 22.1k5 gold badges33 silver badges65 bronze badges asked 6 hours ago KPathakKPathak 492 bronze badges 5 |1 Answer
Reset to default 11["asdf"]
is completely valid C++ code, equivalent to "asdf"[1]
(because reasons). Thus, compiler is confused what do you want to do:
- convert
p1
touint32_t
and use that as subscript to"c0"
- convert
"c0"
tostd::string
and use user-definedoperator[]
.
Both options require one conversion, so both are considered equally good.
There are 3 possible solutions :
- Make you conversion operator
explicit
- this will make it impossible to consider for implicit conversions like here and the conversion can only happen when you usestatic_cast
explicitly:static_cast<std::uint32_t>(p1)
explicit operator uint32_t() const{
return age;
}
- Use actual
std::string
instead ofchar[]
:
p1["c0"s].name = "name";
// or
p1[std::string{"c0"}].name = "name";
- Provide
operator[]
that accepts achar[]
instead - this will mean there is no conversion required and compiler can unambiguously choose this overload:
template <std::size_t N>
child& operator[](const char (&arr)[N] ){
return operator[](std::string{arr});
}
Note that this requires accepting array by reference, since array-to-pointer decay is also a conversion.
本文标签: cCompilation issue when conversion operator is addedStack Overflow
版权声明:本文标题:c++ - Compilation issue when conversion operator is added - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736551401a1944515.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
#include <string>
from your include stack. The use ofstd::string
dictates its presence. – WhozCraig Commented 6 hours agochild
andparent
, that haveage
defined. So where did you add this conversion operator? – PaulMcKenzie Commented 6 hours ago