Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why this error? "no appropriate default constructor available"

Tags:

c++

Someone has given me the following C++ code snippet to try out - and now I have lost contact with them (its a long story). Anyway, it won't compile - I get an error

error C2512: 'mstream' : no appropriate default constructor available

Can anyone explain why, and what is needed to fix it.

class mstream : private ostream
{
  public:

  mstream& operator << (char *value)
  {
    printf ("[%s]\n", value);
    return *this;
  }
  mstream& operator << (int value)
  {
    printf ("[%u]\n", value);
    return *this;
  }

};
mstream g_mcout;

EDIT: Oops, missed this out...

ostream& mcout ()
{
  return g_mcout;
}
ostream& SgDebug ()
{
  return g_mcout;
}

FYI: the reason for this strange looking code is all to do with merging a C++ with a C program. The printf()'s will actually be changed to my_printf()'s which do a wide variety of custom things.

like image 708
Mick Avatar asked Dec 21 '22 22:12

Mick


2 Answers

ostream has no default constructor; the implicitly created default constructor for mstream is invalid because of it. You need to provide the ostream with a stream buffer:

class mstream : private ostream
{
public:
    mstream() :
    ostream(/* whatever you want */)
    {}

    /* Maybe this is more appropriate:

    mstream(std::streambuf* pBuffer) :
    ostream(pBuffer)
    {}

    */

    // ...
};

So it can construct. What you put there depends on what you're trying to do.

like image 171
GManNickG Avatar answered Jan 18 '23 23:01

GManNickG


mstream inherits from ostream, which is a typedef for class template basic_ostream specialized on char. Since you don't define a constructor for mstream the compiler will attempt to provide one using default constructors for ostream to initialize the base class.

However, basic_ostream has no default constructor (with no parameters), so you must provide an mstream constructor with suitable inputs for the base class constructor. Your choices of how to construct the base class are :

explicit basic_ostream(
    basic_streambuf<_Elem, _Tr> *_Strbuf,
    bool _Isstd = false
);
basic_ostream(
    basic_ostream&& _Right
);

and the first is the most sensible choice for you to use, for example like so:

class mstreambuffer : public streambuf
{
public:
    mstreambuffer() : streambuf()
    {
    }
};

class mstream : private ostream
{
public:
    mstream(mstreambuffer* buff) : ostream(buff) {}
};

int main(void)
{
    mstreambuffer buff;
    mstream g_mcout(&buff);
    g_mcout << 32768;
    return 0;
}

mstreambuffer is necessary because streambuf is abstract.

btw besides being uncompilable, this code also uses CRT (printf) instead of more usual C++ output via cout, so it's doubly suspect. Prefer this:

  mstream& operator << (int value)
  {
    std::cout << value << std::endl;
    return *this;
  }
like image 35
Steve Townsend Avatar answered Jan 18 '23 23:01

Steve Townsend