0

我有一个函数可以生成 A 类型对象的映射。

map<int,A> test()
{
    map<int, A> m;
    A a1(10); // constructor
    A a2(20);
    A a3(30);
    m[0] = a1; m[1] = a2; m[2] = a3; // <-- copy constructor and = operator
    return m;
}

当我执行这个函数时,我调用了构造函数,然后调用了复制构造函数和 = 运算符。

map<int,A> x = test();

有没有办法让编译器优化它以只调用一个构造函数,如返回值优化(RVO)呢?

替代方法可能是使用指针,但我想知道是否有另一种方法。

map<int,A*> test3()
{
    map<int, A*> m;
    A* a1 = new A(10);
    A* a2 = new A(20);
    A* a3 = new A(30);
    m[0] = a1; m[1] = a2; m[2] = a3;
    return m;
}

...

map<int,A*> x = test3();

...

for (auto val: x)
{
    delete val.second;
}
4

2 回答 2

1

如果您的实现支持它,请emplace

#include <map>
#include <iostream>

struct A {
    A(int) { std::cout << "ctor\n"; }
    A(const A&) { std::cout << "copy ctor\n"; }
    A(A&&) { std::cout << "move ctor\n"; }
    ~A() { std::cout << "dtor\n"; }
};

std::map<int,A> test()
{
    std::map<int, A> m;
    m.emplace(0, 10);
    m.emplace(1, 20);
    m.emplace(2, 30);
    return m;
}

int main()
{
    std::map<int, A> m = test();
    std::cout << "m.size() = " << m.size() << '\n';
}

输出:

$ ./test
ctor
ctor
ctor
m.size() = 3
dtor
dtor
dtor
于 2013-06-18T03:11:53.877 回答
0

我还用智能指针进行了测试,对我来说似乎很好。

#include <iostream>
#include <map>
#include <memory>

using namespace std;

class A
{
    int x;
public: 
    A() {
        cout << "Default constructor called" << endl;
    }  
    A(const A& rhs) 
    {
        this->x = rhs.x;
        cout << "Copy constructor called" << endl;
    }
    A& operator=(const A& rhs)
    {
        this->x = rhs.x;
        cout << "Copy constructor called" << endl;
    }
    A(int x) : x(x) {
        cout << "*I'm in" << endl;
    }
    ~A() {
        cout << "*I'm out" << endl;
    }
    int get() const {return x;}
    void set(int x) {this->x = x;}
};

std::map<int,unique_ptr<A>> test()
{
    std::map<int, unique_ptr<A>> m;
    m[0] = unique_ptr<A>(new A(101));
    m[1] = unique_ptr<A>(new A(201));
    m[2] = unique_ptr<A>(new A(301));
    return m;
}

using namespace std;
int main(int argc, char *argv[]) {

    auto m = test();
    for (const auto& i: m)
    {
        cout << i.second->get() << endl;
    }    
}

结果:

*I'm in
*I'm in
*I'm in
101
201
301
*I'm out
*I'm out
*I'm out
于 2013-06-18T03:53:09.890 回答