英文:
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>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论