【问题标题】:Pushing back string to vector of objects将字符串推回对象向量
【发布时间】:2015-12-31 02:48:14
【问题描述】:

我正在浏览我为学校项目编写的一些代码,仔细检查后我觉得这些代码很奇怪。我有一个类似于下面的课程:

class Foo {
public:
    Foo(std::string s) : _s(s) {}
private:
    std::string _s;
};

int main() {
    std::string str = "Hiyo";

    std::vector<Foo> f;
    f.push_back(str); // Compiles. Weird to me though.
    f.push_back(Foo(str)); // Predictably, this compiles as well.

    return 0;
}

为什么第一次调用push_back 是一个有效的语句,即使str 不是Foo

【问题讨论】:

    标签: c++ type-conversion implicit-conversion


    【解决方案1】:

    Foo 类有一个非显式 ctor,它采用 std::string 类型的一个参数(即 Converting constructor),这意味着它可以从 std::string 隐式转换。

    f.push_back(str);      // implicit casting from std::string to Foo
    f.push_back(Foo(str)); // explicit casting from std::string to Foo
    

    请注意,如果您将 ctor 设为 explicit,则将禁止隐式转换。

    class Foo {
    public:
        explicit Foo(std::string s) : _s(s) {}
    //  ~~~~~~~~
    private:
        std::string _s;
    };
    

    然后

    f.push_back(str);      // invalid now
    f.push_back(Foo(str)); // still valid
    

    【讨论】:

    • 这应该是公认的答案,因为它谈到了explicit
    【解决方案2】:

    给定string对象,第一次推回会自动初始化Foo对象;通过你的初始化列表。

    (需要一个Foo 对象,得到一个字符串:Foo 对象可以用一个字符串初始化吗?是的,它的初始化列表只有一个元素,并且对象是从那个元素初始化的)。

    详情见例:

    【讨论】:

    • 初始化列表不应该很重要。没有它仍然可以编译。
    • 如果Foo(std::string s)explicit 怎么办?
    【解决方案3】:

    我认为在第一次推回中它会自动初始化Foo(str) 所以基本一样!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-10-03
      • 2017-04-20
      • 2021-12-10
      • 2023-03-23
      • 1970-01-01
      • 2014-05-20
      • 2020-10-15
      • 1970-01-01
      相关资源
      最近更新 更多