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

Discussion in 'C++' started by =?ISO-8859-1?Q?Martin_J=F8rgensen?=, May 6, 2006.

  1. 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
    =?ISO-8859-1?Q?Martin_J=F8rgensen?=, May 6, 2006
    #1
    1. Advertising

  2. =?ISO-8859-1?Q?Martin_J=F8rgensen?=

    John Carson Guest

    "Martin Jørgensen" <> wrote in message
    news:
    > 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
    John Carson, May 6, 2006
    #2
    1. Advertising

  3. =?ISO-8859-1?Q?Martin_J=F8rgensen?=

    Rolf Magnus Guest

    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
    >
    Rolf Magnus, May 6, 2006
    #3
  4. =?ISO-8859-1?Q?Martin_J=F8rgensen?=

    Phlip Guest

    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!!!
    Phlip, May 6, 2006
    #4
  5. =?ISO-8859-1?Q?Martin_J=F8rgensen?=

    Phlip Guest

    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!!!
    Phlip, May 6, 2006
    #5
  6. John Carson wrote:
    > "Martin Jørgensen" <> wrote in message
    > news:
    >
    >>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
    =?ISO-8859-1?Q?Martin_J=F8rgensen?=, May 6, 2006
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    3
    Views:
    372
  2. Alvin
    Replies:
    8
    Views:
    974
  3. C__chp
    Replies:
    4
    Views:
    504
    Puppet_Sock
    Feb 15, 2008
  4. Old Wolf
    Replies:
    0
    Views:
    469
    Old Wolf
    Jan 28, 2009
  5. Marc Bissonnette

    Pattern matching : not matching problem

    Marc Bissonnette, Jan 8, 2004, in forum: Perl Misc
    Replies:
    9
    Views:
    233
    Marc Bissonnette
    Jan 13, 2004
Loading...

Share This Page