compilation error: "error: no matching function for call to 'String::String(String)'

  • Follow


Hello again,

Sorry to bother but I guess my C++ book isn't very good since it 
obviously contains errors so the program code doesn't work with g++.

However I don't understand what the problem is. Last time the problem 
was that "using namespace std" apparently had a "link" class/object 
defined already. Now I get:

error: no matching function for call to 'String::String(String)'

See if you can spot the error because I can't:

- - - - - - - - - - - - - - -
// memory-saving String class
// overloaded assignment and copy constructor
#include <iostream>
#include <cstring>                //for strcpy(), etc.
using namespace std;
////////////////////////////////////////////////////////////////
class strCount                    //keep track of number
{                              //of unique strings
private:
     int count;                  //number of instances
     char* str;                  //pointer to string
     friend class String;        //make ourselves available
                                 //member functions are private 

 
//--------------------------------------------------------------
     strCount(char* s)           //one-arg constructor
         {
         int length = strlen(s);  //length of string argument
         str = new char[length+1];  //get memory for string
         strcpy(str, s);          //copy argument to it
         count=1;                 //start count at 1
         }
     //--------------------------------------------------------------
     ~strCount()                 //destructor
         { delete[] str; }        //delete the string
};
////////////////////////////////////////////////////////////////
class String                      //String class
{
private:
     strCount* psc;              //pointer to strCount
public:
     String()                    //no-arg constructor
     { psc = new strCount("NULL"); }
     //--------------------------------------------------------------
     String(char* s)             //1-arg constructor
     { psc = new strCount(s); }
     //--------------------------------------------------------------
     String(String& S)           //copy constructor
     {
         psc = S.psc;
         (psc->count)++;
     }
     //--------------------------------------------------------------
     ~String()                   //destructor
     {
         if(psc->count==1)        //if we are its last user,
             delete psc;           //   delete our strCount
         else                     //   otherwise,
             (psc->count)--;       //   decrement its count
     }
     //--------------------------------------------------------------
     void display()              //display the String
     {
         cout << psc->str;                 //print string
         cout << " (addr=" << psc << ")";  //print address
     }
     //--------------------------------------------------------------
     void operator = (String& S) //assign the string
     {
         if(psc->count==1)        //if we are its last user,
             delete psc;           //   delete our strCount
         else                     //   otherwise,
             (psc->count)--;       //   decrement its count
         psc = S.psc;             //use argument's strCount
         (psc->count)++;          //increment its count
     }
};
////////////////////////////////////////////////////////////////
int main()
{
     String s3 = "When the fox preaches, look to your geese.";
     cout << "\ns3="; s3.display();   //display s3

     String s1;                       //define String
     s1 = s3;                         //assign it another String
     cout << "\ns1="; s1.display();   //display it

     String s2(s3);                   //initialize with String
     cout << "\ns2="; s2.display();   //display it
     cout << endl;
     return 0;
}

- - - - - - - - - - - - - - -

I didn't make the comments. I just copy/pasted the code so I don't want 
to spend time on removing them as I also find it okay that they're there.


Best regards / Med venlig hilsen
Martin J�rgensen

-- 
---------------------------------------------------------------------------
Home of Martin J�rgensen - http://www.martinjoergensen.dk
0
Reply unoder.spam (554) 5/6/2006 2:48:34 PM

"Martin J�rgensen" <unoder.spam@spam.jay.net> wrote in message
news:4jpui3-2j1.ln1@news.tdc.dk
> Hello again,
>
> Sorry to bother but I guess my C++ book isn't very good since it
> obviously contains errors so the program code doesn't work with g++.
>
> However I don't understand what the problem is. Last time the problem
> was that "using namespace std" apparently had a "link" class/object
> defined already. Now I get:
>
> error: no matching function for call to 'String::String(String)'
>
> See if you can spot the error because I can't:

Change the String copy contructor to take a const reference rather than a 
plain reference (copy constructors should always take const references).


-- 
John Carson


> - - - - - - - - - - - - - - -
> // memory-saving String class
> // overloaded assignment and copy constructor
> #include <iostream>
> #include <cstring>                //for strcpy(), etc.
> using namespace std;
> ////////////////////////////////////////////////////////////////
> class strCount                    //keep track of number
> {                              //of unique strings
> private:
>     int count;                  //number of instances
>     char* str;                  //pointer to string
>     friend class String;        //make ourselves available
>                                 //member functions are private
>
>
> //--------------------------------------------------------------
>     strCount(char* s)           //one-arg constructor
>         {
>         int length = strlen(s);  //length of string argument
>         str = new char[length+1];  //get memory for string
>         strcpy(str, s);          //copy argument to it
>         count=1;                 //start count at 1
>         }
>     //--------------------------------------------------------------
>     ~strCount()                 //destructor
>         { delete[] str; }        //delete the string
> };
> ////////////////////////////////////////////////////////////////
> class String                      //String class
> {
> private:
>     strCount* psc;              //pointer to strCount
> public:
>     String()                    //no-arg constructor
>     { psc = new strCount("NULL"); }
>     //--------------------------------------------------------------
>     String(char* s)             //1-arg constructor
>     { psc = new strCount(s); }
>     //--------------------------------------------------------------
>     String(String& S)           //copy constructor
>     {
>         psc = S.psc;
>         (psc->count)++;
>     }
>     //--------------------------------------------------------------
>     ~String()                   //destructor
>     {
>         if(psc->count==1)        //if we are its last user,
>             delete psc;           //   delete our strCount
>         else                     //   otherwise,
>             (psc->count)--;       //   decrement its count
>     }
>     //--------------------------------------------------------------
>     void display()              //display the String
>     {
>         cout << psc->str;                 //print string
>         cout << " (addr=" << psc << ")";  //print address
>     }
>     //--------------------------------------------------------------
>     void operator = (String& S) //assign the string
>     {
>         if(psc->count==1)        //if we are its last user,
>             delete psc;           //   delete our strCount
>         else                     //   otherwise,
>             (psc->count)--;       //   decrement its count
>         psc = S.psc;             //use argument's strCount
>         (psc->count)++;          //increment its count
>     }
> };
> ////////////////////////////////////////////////////////////////
> int main()
> {
>     String s3 = "When the fox preaches, look to your geese.";
>     cout << "\ns3="; s3.display();   //display s3
>
>     String s1;                       //define String
>     s1 = s3;                         //assign it another String
>     cout << "\ns1="; s1.display();   //display it
>
>     String s2(s3);                   //initialize with String
>     cout << "\ns2="; s2.display();   //display it
>     cout << endl;
>     return 0;
> }
>
> - - - - - - - - - - - - - - -
>
> I didn't make the comments. I just copy/pasted the code so I don't
> want to spend time on removing them as I also find it okay that
> they're there.
>
> Best regards / Med venlig hilsen
> Martin J�rgensen
>
> --
> ---------------------------------------------------------------------------
> Home of Martin J�rgensen - http://www.martinjoergensen.dk



0
Reply jcarson_n_o_sp_am_ (646) 5/6/2006 3:12:03 PM


Martin Jørgensen wrote:

> Hello again,
> 
> Sorry to bother but I guess my C++ book isn't very good since it
> obviously contains errors so the program code doesn't work with g++.
> 
> However I don't understand what the problem is. Last time the problem
> was that "using namespace std" apparently had a "link" class/object
> defined already. Now I get:
> 
> error: no matching function for call to 'String::String(String)'
> 
> See if you can spot the error because I can't:

Well, it would have be much easier to spot if you had included the line
number or better even marked the line that produced the error.

> 
> - - - - - - - - - - - - - - -
> // memory-saving String class
> // overloaded assignment and copy constructor
> #include <iostream>
> #include <cstring>                //for strcpy(), etc.
> using namespace std;
> ////////////////////////////////////////////////////////////////
> class strCount                    //keep track of number
> {                              //of unique strings
> private:
>      int count;                  //number of instances
>      char* str;                  //pointer to string
>      friend class String;        //make ourselves available
>                                  //member functions are private
> 
>  
> //--------------------------------------------------------------
>      strCount(char* s)           //one-arg constructor
>          {
>          int length = strlen(s);  //length of string argument
>          str = new char[length+1];  //get memory for string
>          strcpy(str, s);          //copy argument to it
>          count=1;                 //start count at 1
>          }
>      //--------------------------------------------------------------
>      ~strCount()                 //destructor
>          { delete[] str; }        //delete the string
> };
> ////////////////////////////////////////////////////////////////
> class String                      //String class
> {
> private:
>      strCount* psc;              //pointer to strCount
> public:
>      String()                    //no-arg constructor
>      { psc = new strCount("NULL"); }
>      //--------------------------------------------------------------
>      String(char* s)             //1-arg constructor
>      { psc = new strCount(s); }
>      //--------------------------------------------------------------
>      String(String& S)           //copy constructor

Here is probably the problem. Your copy constructor claims to modify the
original string, because the parameter is a non-const reference. Try:

      String(const String& S)           //copy constructor

Since your whole program doesn't care about const-correctness, I guess
that's the point where your book is failing.

>      {
>          psc = S.psc;
>          (psc->count)++;
>      }
>      //--------------------------------------------------------------
>      ~String()                   //destructor
>      {
>          if(psc->count==1)        //if we are its last user,
>              delete psc;           //   delete our strCount
>          else                     //   otherwise,
>              (psc->count)--;       //   decrement its count
>      }
>      //--------------------------------------------------------------
>      void display()              //display the String
>      {
>          cout << psc->str;                 //print string
>          cout << " (addr=" << psc << ")";  //print address
>      }
>      //--------------------------------------------------------------
>      void operator = (String& S) //assign the string
>      {
>          if(psc->count==1)        //if we are its last user,
>              delete psc;           //   delete our strCount
>          else                     //   otherwise,
>              (psc->count)--;       //   decrement its count
>          psc = S.psc;             //use argument's strCount
>          (psc->count)++;          //increment its count
>      }
> };
> ////////////////////////////////////////////////////////////////
> int main()
> {
>      String s3 = "When the fox preaches, look to your geese.";
>      cout << "\ns3="; s3.display();   //display s3
> 
>      String s1;                       //define String
>      s1 = s3;                         //assign it another String
>      cout << "\ns1="; s1.display();   //display it
> 
>      String s2(s3);                   //initialize with String
>      cout << "\ns2="; s2.display();   //display it
>      cout << endl;
>      return 0;
> }
> 
> - - - - - - - - - - - - - - -
> 
> I didn't make the comments. I just copy/pasted the code so I don't want
> to spend time on removing them as I also find it okay that they're there.
> 
> 
> Best regards / Med venlig hilsen
> Martin Jørgensen
> 

0
Reply ramagnus (3485) 5/6/2006 3:12:56 PM

Martin J�rgensen wrote:

> I guess my C++ book isn't very good since it obviously contains errors so 
> the program code doesn't work with g++.

Get /Accelerated C++/ by Koenig and Moo, so you can skip over these 
low-level issues and learn to write useful programs sooner. And read more 
than 3 tutorials.

> However I don't understand what the problem is. Last time the problem was 
> that "using namespace std" apparently had a "link" class/object defined 
> already. Now I get:

And that's a reason not to use 'using namespace std'.

> error: no matching function for call to 'String::String(String)'

On what line? Next time comment such a line with // <-- error

>     String(String& S)           //copy constructor

Make that String(String const & S). Without the 'const', the compiler 
automatically generates another copy constructor for you, with the signature 
String(String const & S). Then on this line...

>     String s2(s3);                   //initialize with String

....the compiler can't disambiguate the two calls, or something.

-- 
  Phlip
  http://c2.com/cgi/wiki?ZeekLand <-- NOT a blog!!! 


0
Reply phlipcpp (2479) 5/6/2006 3:18:41 PM

Phlip wrote:

>>     String(String& S)           //copy constructor
>
> Make that String(String const & S). Without the 'const', the compiler 
> automatically generates another copy constructor for you, with the 
> signature String(String const & S). Then on this line...
>
>>     String s2(s3);                   //initialize with String
>
> ...the compiler can't disambiguate the two calls, or something.

Reviewing the other two posts, I now realize I was the closest to the 
answer. Strike "or something".

When a compiler can't disambiguate two calls, it declares that it can't find 
the simplest thing that it was looking for. For example:

    void foo(short x);
    void foo(long x);
    foo(10);  // <-- will report a missing foo(int)

So the simplest thing it can infer from String s2(s3) is 
String::String(String). So the error message asks for that constructor, 
instead of the canonical String::String(String const &).

(Despite String::String(String) is an impossible constructor, which is an 
unrelated point. If you wrote a copy constructor without any &, then s3 
would call that copy constructor to copy into the parameter argument. And 
that would recursively call the same copy constructor forever.)

I win!

-- 
  Phlip
  http://c2.com/cgi/wiki?ZeekLand <-- NOT a blog!!!


0
Reply phlipcpp (2479) 5/6/2006 3:42:13 PM

John Carson wrote:
> "Martin J�rgensen" <unoder.spam@spam.jay.net> wrote in message
> news:4jpui3-2j1.ln1@news.tdc.dk
> 
>>Hello again,
>>
>>Sorry to bother but I guess my C++ book isn't very good since it
>>obviously contains errors so the program code doesn't work with g++.
>>
>>However I don't understand what the problem is. Last time the problem
>>was that "using namespace std" apparently had a "link" class/object
>>defined already. Now I get:
>>
>>error: no matching function for call to 'String::String(String)'
>>
>>See if you can spot the error because I can't:
> 
> 
> Change the String copy contructor to take a const reference rather than a 
> plain reference (copy constructors should always take const references).

Thanks! Problem solved.


Best regards / Med venlig hilsen
Martin J�rgensen

-- 
---------------------------------------------------------------------------
Home of Martin J�rgensen - http://www.martinjoergensen.dk
0
Reply unoder.spam (554) 5/6/2006 3:48:56 PM

5 Replies
31 Views

(page loaded in 1.206 seconds)


Reply: