Skip to content

Instantly share code, notes, and snippets.

@vittorioromeo
Last active December 22, 2015 17:59
Show Gist options
  • Select an option

  • Save vittorioromeo/6509614 to your computer and use it in GitHub Desktop.

Select an option

Save vittorioromeo/6509614 to your computer and use it in GitHub Desktop.

Inspired by my own StackOverflow question: [Should I always move on sink constructor or setter arguments?] (http://stackoverflow.com/questions/18673658/should-i-always-move-on-sink-constructor-or-setter-arguments)

Problem: passing sink arguments efficiently either requires performance trade-offs or extensive code duplication



Current possible approaches

Approach 1

Pass by value and std::move

struct Example {
    std::string s1, s2;
    Example(std::string mS1, std::string mS2) : s1{std::move(mS1)}, s2{std::move(mS2)} { } 
};
  • Passed argument is a temporary: it is moved without copies. Result: 1 move.

  • Passed argument is an lvalue: it is copied, then moved. Result: 1 copy + 1 move.

  • Pros: no code duplication.

  • Cons: unnecessary move when the passed argument is an lvalue.


Approach 2

Multiple constructors: pass by const& and &&

struct Example {
    std::string s1, s2;
    Example(std::string&& mS1,      std::string&& mS2)      : s1{std::move(mS1)}, s2{std::move(mS2)} { } 
    Example(const std::string& mS1, std::string&& mS2)      : s1{mS1}, s2{std::move(mS2)} { } 
    Example(std::string&& mS1,      const std::string& mS2) : s1{std::move(mS1)}, s2{mS2} { } 
    Example(const std::string& mS1, const std::string& mS2) : s1{mS1}, s2{mS2} { } 
};
  • Passed argument is a temporary: it is moved without copies. Result: 1 move.

  • Passed argument is an lvalue: it is just copied. Result: 1 copy.

  • Pros: most efficient behavior and code generation.

  • Cons: requires n^2 constructors/functions written by the developer!



Proposal: passing with std::sink<T> by value - behaves identically to Approach 2, avoids code duplication

struct Example {
    std::string s1, s2;
    Example(std::sink<std::string> mS1, std::sink<std::string> mS2) : s1{mS1}, s2{mS2} { } 
};

Thoughts?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment