Reputation: 451
I have a class like that.I want to use reference for string but it doesnt work.How can i use string& ?
#include <string>
using namespace std;
class T
{
public:
T(string& s);
private:
string s;
};
T::T(string& s)
{
this->s = s;
}
int main(void)
{
T t("Test Object");
return 0;
}
Error : 'T::T(std::string &)' : cannot convert parameter 1 from 'const char [12]' to 'std::string &'
Upvotes: 5
Views: 6426
Reputation: 56549
Use const
:
class T
{
public:
T(const string& ss);
private:
string s;
};
T::T(const string& ss) : s(ss)
{
}
"Test Object"
will be constructed as a const
string
before passing to T
's constructor, so the constructor has to accept a const string
.
Upvotes: 6
Reputation: 43044
In C++98/03, if you have a class that is not cheap to copy (e.g. an int
or a double
are cheap to copy, a std::string
isn't, since its copy can involve allocating new heap memory, copying characters from source to destination, etc.), then the rule is to pass by const
reference const std::string&
:
class T
{
public:
T(const string& s); // <--- const string&
private:
string m_s;
};
And then in constructor do:
T::T(const string& s)
: m_s(s)
{}
However, in C++11, where move semantics is available, the new rule seems to be: if you need a copy (and the object is cheap to move, as it normally should be), pass by value and move from the value:
T::T(string s) // pass by value
: m_s( std::move(s) ) // and move from the value
{}
(The optimal thing would be to offer a couple of overloads, passing by const &
and passing by value, but probably this is not necessarily in all applications, but only when you need to squeeze performance.)
Note that when you don't need a copy, and just need to observe the parameter, the usual C++98/03 pass by const &
rule is still valid.
Upvotes: 2
Reputation: 9696
You're not passing in a std::string. As it says, it can't convert from const char array to string-ref. Change the constructor to take a const-ref and it'll work. This is because a temporary string will have to be created from the char-array, and you can only make const-references to temporaries to stop you getting confused (if you modify the temporary, the changes are just going to be discarded, so the language stops you from doing that).
Upvotes: 2
Reputation: 42133
The constructor you defined takes a std::string
by reference:
T::T(std::string& s)
{
this->s = s;
}
thus the most straightforward thing to do would be to create a std::string
object, that will be passed to this constructor:
std::string s("Test Object");
T t(s);
But since your constructor doesn't change the std::string
you pass to it (it is just used to set the value of T
's data member) you should pass const
reference: T::T(const string& s)
. Also instead of letting the data member s
being constructed and assigning another string into it later, it would be better if you construct this member directly within an initialization list:
T::T(const std::string& str) : s(str) { }
Upvotes: 2
Reputation: 13217
References need to be intialized using the initialiser-list of the constructor. Change your constructor to:
T::T(string& s) : s(s)
{
}
Additionally define your member s
as std::string& s
to be able to take a reference.
Maybe change the name of s to avoid ambiguities.
See this entry on SO.
Upvotes: 0