vendredi 1 avril 2016

How can I perform perfect forwarding without using templates?

I want perfect forwarding but I already know (and only accept) the type my function will take.

Here is a quick example I typed up:

class big_class
{
private:
    std::string m_somethingBig;
};

class testmove
{
public:

    void Add(big_class&& big)
    {
        std::cout << "Add via move\n";
        m_bigClasses.push_back(std::move(big));
    }

    void Add(big_class const& big)
    {
        std::cout << "Add via copy\n";
        m_bigClasses.push_back(big);
    }

private:

    std::vector<big_class> m_bigClasses;
};

int main()
{
    testmove tm;

    big_class big;
    tm.Add(big);

    tm.Add(big_class{});
}

Live Sample

Is it possible to do some form of implementation sharing between the two overloads of testmove::Add()? I want to optimize for move, and if someone does std::move() without my rvalue overload it will end up doing at least 1 copy before it is added to my vector.

Again, I realize I can solve this problem by making Add() a template function, and even using type traits and some template trickery. But I wanted to avoid this if possible. If you need to know why, I have a few reasons:

  • I can't do implementation hiding with a template (restrict includes and symbol visibility to a single translation unit)
  • Using a template here gives me more flexibility than I want (My contract requires I only use a big_class).
  • Using a template would impact readability/maintainability for what should be a simple interface.

Aucun commentaire:

Enregistrer un commentaire