Question Details

No question body available.

Tags

c++ code-duplication

Answers (3)

Accepted Answer Available
Accepted Answer
November 9, 2025 Score: 10 Rep: 38,114 Quality: Expert Completeness: 70%

The implementation of the methods should not be the same:

  • The 1st one (getting const T& value) should copy the element into the container.
  • The 2nd one (getting T&& value) should move the element into the container.

Supplying a different implementation is possible, but will likely confuse the users of the container. This is because when a method accepts an R-value reference (T && value here) it signals it can take ownership of the object.

November 9, 2025 Score: 8 Rep: 45,209 Quality: Medium Completeness: 70%

It should be

template 
void pushfront(T&& value) {
  // ...
  newhead->value = std::forward(value);
  // ...
}

If value is U&& then it will give newhead->value = std::move(value);

If value is const U& then it will give newhead->value = value;

See When is a reference a forwarding reference, and when is it an rvalue reference?, Is there a difference between universal references and forwarding references?

November 9, 2025 Score: 6 Rep: 1,119 Quality: Medium Completeness: 60%

Generally speaking, making two functions with different arguments share a function body requires you to find out if one could be implemented in terms of another, or if it's possible to extract a third function from them.

For the exact scenario in your code, which is typically a pushfront implementation that copies lvalues and moves rvalues, there are two common ways:

One is support another function usually named emplacefront, which accepts anything and just move-construct the object from the arguments. It is actually a generalization of @3CEZVQ's answer.

template 
void emplacefront(Ts... &&args) {
  // ...
  // Initialize it with args... forwarded.
  newhead->value = T(std::forward(args)...);
  // ...
}
void pushfront(const T &value) {
  emplacefront(value);
}
void pushfront(T &&value) {
  emplacefront(std::move(value));
}

The other way is to simply pass by value. When the argument is passed in by value, lvalue is copied and rvalue is moved, which is exactly what we hope to do. Then we only need to move it to newhead->value. But this is under the assumption that the value type T is cheaply movable, because we perform an additional move of it.

void pushfront(T value) {
  // ...
  // Initialize it with std::move(value)
  newhead->value = T(std::move(value));
  // ...
}

Note: You did not make clear what T is. I'm just assuming it is the value type of the linked-list and is not the template parameter of pushfront.