Quick Question

In this code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
// Ex8_11.cpp
// Perfect forwarding
#include <iostream>
#include <utility>
#include <string>
using std::string;
using std::cout;
using std::endl;
using std::forward;
using std::move;

class Name
{
public:
  Name(string& aName) : name(aName)
  {
    cout << "Lvalue Name constructor." << endl;
  }


  Name(string&& aName) : name(move(aName))
  {
    cout << "Rvalue Name constructor." << endl;
  }

  const string& getName() const { return name; }

private:
  string name;
};

class Person
{
public:
  // Constructor template
  template<class T1, class T2>
  Person(T1&& first, T2&& second) :
    firstname(forward<T1>(first)), secondname(forward<T2>(second)) {}
//    firstname(first), secondname(second) {}

  string getName() const
  {
    return firstname.getName() + " " + secondname.getName();
  }

private:
  Name firstname;
  Name secondname;
};

int main()
{
  cout << "Creating Person(string(\"Ivor\") , string(\"Horton\")) - rvalue arguments:" << endl;
  Person me(string("Ivor") , string("Horton"));
  cout << "Person is " << me.getName() << endl << endl;

  string first("Fred");
  string second("Fernackerpan");
  cout << "Creating Person(first , second) - lvalue arguments:" << endl;
  Person other(first,second);
  cout << "Person is " << other.getName() << endl << endl;

  cout << "Creating Person(first , string(\"Bloggs\")) - lvalue, rvalue arguments:" << endl;
  Person brother(first , string("Bloggs"));
  cout << "Person is " << brother.getName() << endl << endl;

  cout << "Creating Person(\"Richard\" , \"Horton\")) - rvalue const char* arguments:" << endl;
  Person another("Richard", "Horton");
  cout << "Person is " << another.getName() << endl << endl;


  return 0;
}


Why in line 68 does the Person Constructor create the class successfully? It shouldn't be able to because you are passing a string literal and not a string object, which means it shouldn't be able to select any of the overload constructors from the name class?

Am I missing anything or is it just like that, a string literal can be considered a string object?
Last edited on
A string litereal is convertible to a string object. If you want to be pedantic, the compiler applies an lvalue transformation (lvalue array to rvalue pointer) and a user-defined conversion (non-explicit single-argument constructor).
Oh so the compiler applies a implicit cast?
Yes, that's part of overload resolution. The overload that can be called with the simplest implicit conversion sequence is the one that's chosen.
Thanks :P
Also what do you mean overload resolution?
Topic archived. No new replies allowed.