The Best Way to Define Constructor

Assuming the capacity of the member to be constructed is zero.

Short answer

For movable object

// For lvalue/rvalue
Person(std::string n) : name{std::move(n)} {}

For non-movable object

// For lvalue
Person(const std::string& n) : name{n} {}
// For rvalue
Person(std::string&& n) : name{std::move(n)} {}

or

// For lvalue/rvalue
Person(const std::string& n) : name{n} {}

Lvalue Argument

Pass-by-value

GCC: https://quick-bench.com/q/TAj4y76nTywf73Dit6hok_dCBA0

Clang: https://quick-bench.com/q/9cXSSD5AZ7VC0cwdYBK-fq4pKUM

class Person {
public:
   Person(std::string n) : name{std::move(n)} {}
   //Person(const std::string& n) : name{n} {}
   //Person(std::string&& n) : name{std::move(n)} {}
private:
   std::string name;
};

static void TakeValue_lvalue(benchmark::State& state) {
  // Code inside this loop is measured repeatedly
  std::string name = "Constantdw wwdw dqwdfqwyypfn;qwlnm5465";
  for (auto _ : state) {
    Person person(name);
    benchmark::DoNotOptimize(person);
  }
}
BENCHMARK(TakeValue_lvalue);

Pass-by-reference

GCC: https://quick-bench.com/q/Di-71lEKR30kBict_AMGOOGLRWU

Clang: https://quick-bench.com/q/W7RzNVMf0ga4mxq9IS0r6LYd1GU

class Person {
public:
   //Person(std::string n) : name{std::move(n)} {}
   Person(const std::string& n) : name{n} {}
   //Person(std::string&& n) : name{std::move(n)} {}
private:
   std::string name;
};

static void TakeValue_lvalue(benchmark::State& state) {
  // Code inside this loop is measured repeatedly
  std::string name = "Constantdw wwdw dqwdfqwyypfn;qwlnm5465";
  for (auto _ : state) {
    Person person(name);
    benchmark::DoNotOptimize(person);
  }
}
BENCHMARK(TakeValue_lvalue);

Rvalue Argument

Pass-by-value

class Person {
public:
   Person(std::string n) : name{std::move(n)} {}
   //Person(const std::string& n) : name{n} {}
   //Person(std::string&& n) : name{std::move(n)} {}
private:
   std::string name;
};

static void rvalue(benchmark::State& state) {
  // Code inside this loop is measured repeatedly
  std::string name = "Constantdw wwdw dqwdfqwyypfn;qwlnm5465";
  for (auto _ : state) {
    Person person(std::move(name));
    benchmark::DoNotOptimize(person);
  }
}
BENCHMARK(rvalue);

GCC: https://quick-bench.com/q/GjLYdlyRLPiwGEgmVulHDtbzReQ Clang: https://quick-bench.com/q/Mlt4tRPB6wuqsd6svDZaUFxvblg

Pass-by-reference

class Person {
public:
   //Person(std::string n) : name{std::move(n)} {}
   Person(const std::string& n) : name{n} {}
   //Person(std::string&& n) : name{std::move(n)} {}
private:
   std::string name;
};

static void rvalue(benchmark::State& state) {
  // Code inside this loop is measured repeatedly
  std::string name = "Constantdw wwdw dqwdfqwyypfn;qwlnm5465";
  for (auto _ : state) {
    Person person(std::move(name));
    benchmark::DoNotOptimize(person);
  }
}
BENCHMARK(rvalue);

GCC: https://quick-bench.com/q/H_33D9MRmpfUJdy8_zaCbP504-Q Clang: https://quick-bench.com/q/LNzBy3uBlVRC22PBVLW8xafCT1o

Pass-by-rvalue-reference

class Person {
public:
   //Person(std::string n) : name{std::move(n)} {}
   //Person(const std::string& n) : name{n} {}
   Person(std::string&& n) : name{std::move(n)} {}
private:
   std::string name;
};

static void rvalue(benchmark::State& state) {
  // Code inside this loop is measured repeatedly
  std::string name = "Constantdw wwdw dqwdfqwyypfn;qwlnm5465";
  for (auto _ : state) {
    Person person(std::move(name));
    benchmark::DoNotOptimize(person);
  }
}
BENCHMARK(rvalue);

GCC: https://quick-bench.com/q/MjO6qPy4y2Q_MDF1rn3CfVUMExk Clang: https://quick-bench.com/q/ewH4cWNZOf6_r24Qea2w8BNvzHs

Summary

| | lvalue argument | rvalue argument | |:—————————————-:| ————————————————– | ——————————————– | | ` Person(std::string n) : name{std::move(n)} {} |1. Copy construct n from lvalue arg<br>2. Move construct | 1. Move construct n from rvalue arg<br>2. Move construct | | Person(const std::string& n) : name{n} {} | 1. Bind n to lvalue arg<br>2. Copy construct | 1.Bind n to rvalue arg<br>2. Copy construct | | Person(std::string&& n) : name{std::move(n)} {} | N/A | 1. Bind n` to rvalue arg
2. Move construct |