为什么在插入到映射中时隐式转换不起作用

huangapple go评论55阅读模式
英文:

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&lt;const std::string, int&gt;, not std::pair&lt;std::string, int&gt; 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&lt;const std::string, int&gt;, 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&lt;std::string, int&gt; to std::pair&lt;const std::string, int&gt;.


Changing your operator to operator std::pair&lt;const std::string, int&gt;() 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>

huangapple
  • 本文由 发表于 2023年6月8日 01:41:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/76425843.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定