Effective Modern C++

【Effective Modern C++(8)】其他轻微调整

2018-12-29  本文已影响21人  downdemo

41 对于可拷贝的形参,如果移动成本低且一定会被拷贝则考虑传值

class Widget {
public:
    void addName(const std::string& newName)
    { names.push_back(newName); }

    void addName(std::string&& newName)
    { names.push_back(std::move(newName)); }
    …
private:
    std::vector<std::string> names;
};
class Widget {
public:
    template<typename T>
    void addName(T&& newName)
    {
        names.push_back(std::forward<T>(newName)); // move rvalues;
    }
    …
};
class Widget {
public:
    void addName(std::string newName) // 可接受左值和右值,对右值移动
    { names.push_back(std::move(newName)); }
    …
};
Widget w;
…
std::string name("Bart");
w.addName(name); // 以传左值的方式调用
…
w.addName(name + "Jenne"); // 以传右值的方式调用
class Widget {
public:
    void addName(const std::string& newName)
    { names.push_back(newName); }
    void addName(std::string&& newName)
    { names.push_back(std::move(newName)); }
    …
private:
    std::vector<std::string> names;
};

class Widget {
public:
    template<typename T>
    void addName(T&& newName)
    { names.push_back(std::forward<T>(newName)); }
    …
};

class Widget {
public:
    void addName(std::string newName)
    { names.push_back(std::move(newName)); }
    …
};
Widget w;
…
std::string name("Bart");
w.addName(name); // pass lvalue
…
w.addName(name + "Jenne"); // pass rvalue
class Widget {
public:
    …
    void setPtr(std::unique_ptr<std::string>&& ptr)
    { p = std::move(ptr); }
private:
    std::unique_ptr<std::string> p;
};

Widget w;
…
w.setPtr(std::make_unique<std::string>("Modern C++"));
class Widget {
public:
    …
    void setPtr(std::unique_ptr<std::string> ptr)
    { p = std::move(ptr); }
    …
};
class Widget {
public:
    void addName(std::string newName)
    {
        if ((newName.length() >= minLen) &&
            (newName.length() <= maxLen))
        {
            names.push_back(std::move(newName));
        }
    }
    …
private:
    std::vector<std::string> names;
};
class Password {
public:
    explicit Password(std::string pwd)
    : text(std::move(pwd)) {} // 对text采用构造
    void changeTo(std::string newPwd)
    { text = std::move(newPwd); } // 对text采用赋值
    …
private:
    std::string text;
};
std::string initPwd("Supercalifragilisticexpialidocious");
Password p(initPwd);
std::string newPassword = "Beware the Jabberwock";
p.changeTo(newPassword);
class Password {
public:
    …
    void changeTo(const std::string& newPwd) // 用于左值的重载版本
    {
        text = newPwd; // can reuse text's memory if text.capacity() >= newPwd.size()
    }
    …
private:
    std::string text;
};
class Widget { … }; // 基类
class SpecialWidget: public Widget { … }; // 派生类
void processWidget(Widget w); // 接受任何Widget或其派生类
…
SpecialWidget sw;
…
processWidget(sw); // processWidget只能看到一个Widget而不是一个SpecialWidget

42 使用emplace操作替代insert操作

std::vector<std::string> vs; // container of std::string
vs.push_back("xyzzy"); // add string literal
template <class T, class Allocator = allocator<T>>
class vector {
public:
    …
    void push_back(const T& x); // insert lvalue
    void push_back(T&& x); // insert rvalue
    …
};
vs.push_back(std::string("xyzzy"));
vs.emplace_back("xyzzy");
vs.emplace_back(50, 'x'); // insert std::string consisting of 50 'x' characters
std::string queenOfDisco("Donna Summer");
// 下面两个调用的效果相同
vs.push_back(queenOfDisco);
vs.emplace_back(queenOfDisco);
std::list<std::shared_ptr<Widget>> ptrs;
void killWidget(Widget* pWidget);
ptrs.push_back(std::shared_ptr<Widget>(new Widget, killWidget));
// 或者如下,意义相同
ptrs.push_back({ new Widget, killWidget });
std::shared_ptr<Widget> spw(new Widget, killWidget);
ptrs.push_back(std::move(spw));
std::shared_ptr<Widget> spw(new Widget, killWidget);
ptrs.emplace_back(std::move(spw));
std::vector<std::regex> regexes;
regexes.emplace_back(nullptr);
std::regex r = nullptr; // 编译错误
regexes.push_back(nullptr); // 编译错误
std::regex upperCaseWord("[A-Z]+"); // OK
std::regex r(nullptr); // 能编译但会引发异常
上一篇 下一篇

猜你喜欢

热点阅读