英文:
Why implicit conversion doesn't work when inserting to map
问题
I have a structure that is implicitly convertable to the type that is acceptable by the std::map::insert() function.
我有一个结构体,它可以隐式转换为std::map::insert()函数接受的类型。
I use a structure as-is, but I have compilation error:
我直接使用这个结构体,但是出现了编译错误:
> no overloaded function could convert all the argument types
> 没有重载的函数能够转换所有的参数类型
However, if I explicitly convert the structure using static_cast, it is accepted.
然而,如果我使用static_cast显式转换结构体,它可以被接受。
My question is, why does implicit conversion not work here?
我的问题是,为什么隐式转换在这里不起作用?
Example code:
struct MyStruct
{
MyStruct(std::string s, int i) : data(s, i) {}
operator std::pair<std::string, int>() const
{
return data;
}
private:
std::pair<std::string, int> data;
};
MyStruct my_val1("hello", 4);
MyStruct my_val2("world", 2);
std::map<std::string, int> my_map {};
my_map.insert(static_cast<std::pair<std::string, int>>(my_val1)); // compiles
my_map.insert(my_val2); // not compiles
示例代码:
struct MyStruct
{
MyStruct(std::string s, int i) : data(s, i) {}
operator std::pair<std::string, int>() const
{
return data;
}
private:
std::pair<std::string, int> data;
};
MyStruct my_val1("hello", 4);
MyStruct my_val2("world", 2);
std::map<std::string, int> my_map {};
my_map.insert(static_cast<std::pair<std::string, int>>(my_val1)); // 编译通过
my_map.insert(my_val2); // 无法编译通过
英文:
I have a structure that is implicitly convertable to the type that is acceptable by the std::map::insert() function.
I use a structure as-is, but I have compilation error:
> no overloaded function could convert all the argument types
However, if I explicitly convert the structure using static_cast, it is accepted.
My question is, why does implicit conversion not work here?
Example code:
struct MyStruct
{
MyStruct(std::string s, int i) : data(s, i) {}
operator std::pair<std::string, int>() const
{
return data;
}
private:
std::pair<std::string, int> data;
};
MyStruct my_val1("hello", 4);
MyStruct my_val2("world", 2);
std::map<std::string, int> my_map {};
my_map.insert(static_cast<std::pair<std::string, int>>(my_val1)); // compiles
my_map.insert(my_val2); // not compiles
答案1
得分: 13
Your issue is that value_type of my_map is std::pair<const std::string, int>, not std::pair<std::string, int> like you have for your conversion operator.
This means that converting my_val2 requires two user-defined conversions to get to std::pair<const std::string, int>, but you are only ever allowed to have up to one user-defined conversion in an implicit conversion sequence.
The static_cast works as that is an explicit cast, so there is just the one implicit user-defined conversion to go from std::pair<std::string, int> to std::pair<const std::string, int>.
Changing your operator to operator std::pair<const std::string, int>() const will allow my_map.insert(my_val2); to compile, as seen in this live example.
1: even standard library types are considered user-defined. Non-user-defined types are things that the core language supports, like int.
英文:
Your issue is that value_type of my_map is std::pair<const std::string, int>, not std::pair<std::string, int> like you have for your conversion operator.
This means that converting my_val2 requires two user-defined conversions<sup>1</sup> to get to std::pair<const std::string, int>, but you are only ever allowed to have up to one user-defined conversion in an implicit conversion sequence.
The static_cast works as that is an explicit cast, so there is just the one implicit user-defined conversion to go from std::pair<std::string, int> to std::pair<const std::string, int>.
Changing your operator to operator std::pair<const std::string, int>() const will allow my_map.insert(my_val2); to compile, as seen in this live example.
<sup>1: even standard library types are considered user-defined. Non user-defined types are things that the core language supports, like int.</sup>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论