ProblemsTemplatesThe constructor that steals copies
AdvancedTemplates

The constructor that steals copies

Context

The class has two constructors: a template one (from a number) and a copy constructor. Write Value b(a) — and the build breaks. For a non-const a the compiler considers the template a better match than the copy constructor, and it tries to make a string out of a Value. The template needs to be told: "never accept Value".

Task

Value b(a) does not call the copy constructor. The template constructor Value(U&&) wins the overload — and tries std::to_string on a Value, which breaks the build. Restrict the template (enable_if + is_same) so it ignores Value itself.

Constraints

  • Constructing from numbers must keep working through the template constructor (do not replace it with fixed overloads)
  • Value b(a) from a non-const lvalue must invoke the real copy constructor (the copy counter proves it)
  • Use a SFINAE constraint (std::enable_if_t + std::decay_t/std::is_same_v) to exclude Value itself
  • Copying from a const Value keeps working too

Before you code

  • Why is U = Value& a better match for Value b(a) than const Value& of the copy constructor?
  • What does std::decay_t<U> strip, and why compare the decayed type?
  • Where else does this trap bite? (hint: look at any single-argument forwarding constructor)

Tests

  • #1Builds from numbers via the template
  • #2Copying a non-const Value uses the copy constructor
  • #3Copying a const Value still works

Hints

Hint 1

For Value b(a) with non-const a, the template deduces U = Value& — a perfect match, while the copy constructor needs a const-qualification. That is why the template wins.

Hint 2

Add a default template parameter that SFINAEs the constructor away when std::decay_t<U> is Value.

Editorgreedy-forwarding-constructor.cpp
Results

Hit Submit (or ⌘/Ctrl + ↵) — test results will show up here.

The constructor that steals copies — CppForge