Visual Studio Error C2248

Greetings -- Please consider the following contentents of file TMDefinition.h, and how it might be leading to the intractible Error C2248 (described below) in Visual Studio.

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

#include <iostream>
#include <fstream>
#include "StringVector.h"

using namespace std;

class TMDefinitionStream : public ifstream
{
private:
    StringVector keywords;
    string lastKeywordRead;
public:
    TMDefinitionStream(string fileName);        // This is the nexus of Error C2248
    bool Next_Word(string& toRead, bool& isKeyWord);
    string Last_Keyword_Read();      
};

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

Error   1   error C2248: 'std::basic_ios<_Elem,_Traits>::basic_ios' : cannot access private member declared in class 'std::basic_ios<_Elem,_Traits>'  c:\users\gary\documents\visual studio 2010\projects\tmree\tmree\tmdefinitionstream.h      20      1      TMREe

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

1. This is the only error in the entire project.

2. By commenting out the several elements of the class definition, I find that the error seems to be centered on the constructor.  Without a constructor, the compiler complains about lots of OTHER things, but not C2248.  With the constructor, there will always be a C2248.  This is despite the fact that the error message itself points to line 20, which is the closing brace of the class definition.

3. The entire class definition is perfectly fine IN ITS CURRENT FORM if moved to main.cpp.  In that case, I had to alter the name of the class slightly, but that's all.  This leads me to think that perhaps something that *follows* TMDefinition.h is tripping it up.  That may be, but in the entire project TMDefinition.h is never the *last* header file called out.  I guess what I would be looking for here is if anyone can image what cockamamee thing might be in the next header file - that only comes up when this header file preceeds it - that would result in error E2248.

This project is an implementation of a Turing Machine for a college class I am taking.  One of the rules is that we can use no library other than the standard library.  Therefore, I cannot accept any solution that would violate that rule.  Beyond that, I started this as an "empty" project to make it as standard C++ as possible.  It will eventually have to be ported to a G++ compiler running on Ubuntu.

**** Many Thanks *****
NonComposMentisAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

jkrCommented:
What does 'StringVector.h' look like? The snippet you gave - with only small changes - compiles fine:

#include <iostream>
#include <fstream>
//#include "StringVector.h"

using namespace std;

class TMDefinitionStream : public ifstream
{
private:
    //StringVector keywords;
    string lastKeywordRead;
public:
    TMDefinitionStream(string fileName);        // This is the nexus of Error C2248
    bool Next_Word(string& toRead, bool& isKeyWord);
    string Last_Keyword_Read();      
};

Open in new window


All that VC++ 10 complains about the above is that 'main()' is missing (well, for sure), which makes me think that there is an issue with the aforementioned header file...
NonComposMentisAuthor Commented:
Thanks, jkr:  here is StringVector.h

#ifndef StringVector_h
#define StringVector_h

#include <string>	// #include<string> must come before #include <vector>
#include <vector>

using namespace std;

class StringVector : public vector<string>
{
private:
	bool isCaseSensitive;

public:
	void Case_Sensitivity(bool isCaseSensitive);
	bool Is_In_Vector(const string& testString) const;
	bool Enqueue_Unique(const string& addString);
};

#endif

Open in new window

jkrCommented:
Nope, no way, won't get the error with the above - not even a warning...
Python 3 Fundamentals

This course will teach participants about installing and configuring Python, syntax, importing, statements, types, strings, booleans, files, lists, tuples, comprehensions, functions, and classes.

NonComposMentisAuthor Commented:
Well, OK.  As I stated originally, I don't get the error either if I take the whole business and move it to main.cpp.  There is something about *where* it is or how it is used.  The compiler's message is not that helpful to me.  I was hoping perhaps someone else could decipher "cannot access private member declared in class 'std::basic_ios<_Elem,_Traits>'".
ZoppoCommented:
Hi NonComposMentis,

I guess the problem is somewhere else in your code, I think the base class ifstream cannot be copied - do you anywhere create a copy of a TMDefinitionStream instance (can even be a function call where such an instance is passed by value instead of by reference). For any reason in this case VS 2010 shows an error in the class declaration without hint where the problem comes from.

I.e. take a look at this code:
class TMDefinitionStream  : public std::ifstream
{
public:
	TMDefinitionStream ( std::string fileName ) {}
};
TMDefinitionStream t1( "test.txt" );

Open in new window

This should compile fine - now add this line:
TMDefinitionStream t2( t1 );

Open in new window

Now VS 2010 reports the same error.

Hope that helps,

ZOPPO

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
ZoppoCommented:
... the same happens for code like
TMDefinitionStream t2 = t1;

Open in new window

or
void foo( TMDefinitionStream t2 ) {}
...
foo( t1 );

Open in new window

ZoppoCommented:
... and, JFI, another possibility is returning a TMDefinitionStream - I once had the problem when I ported code from VC++ 6 to VS 2008, there was an overloaded shift operator like this:
class TMDefinitionStream  : public std::ifstream
{
public:
	TMDefinitionStream TMDefinitionStream::operator >> ( std::vector< std::string > v )	{ return *this; }
};

Open in new window

This compiled (and, at least how we used it, it worked) fine in VC++ 6, in VS 2010 I got the same error 2248 without any hint where the problem comes from (in a file with > 2000 lines).

In VS 2010 this has to be implemented like this:
class TMDefinitionStream  : public std::ifstream
{
public:
	TMDefinitionStream& TMDefinitionStream::operator >> ( std::vector< std::string > v )	{ return *this; } // return value must be a reference
};

Open in new window

ZOPPO
NonComposMentisAuthor Commented:
Just about every class in the project gets a turn at the "Turing machine definition stream", and yes, some of them were passed copies instead of references.  When I started this project I thought objects were *always* passed by reference.  Guess not in this language.  Many thanks!
ZoppoCommented:
Yes, in C/C++ values can be either passed by value or by reference (in C only possible with pointers) - i.e. take a look here about more info:
http://www.cplusplus.com/doc/tutorial/functions2/
http://en.wikipedia.org/wiki/Evaluation_strategy

Have a nice day,

best regards,

ZOPPO
evilrixSenior Software Engineer (Avast)Commented:
>> using namespace std;

Unrelated to the problem but... having this in a header file is a really bad idea and just a problem waiting to happen. Trust me, you don't want to go polluting all your code with a namespace via a header file.
NonComposMentisAuthor Commented:
So inside the header files, I just use "std::" everywhere?  I was kind of under the impression I had to use "using namespace std;" in each *file* that it was used in.  In other words, the header files would not "pollute" the cpp files, as you say.  But you're right.  I just tested it and calling out the namespace is unnecessary in the cpp file if it is done in the header.  That being the case, I can see the potential for conflicts.  Thanks!
evilrixSenior Software Engineer (Avast)Commented:
>> So inside the header files, I just use "std::" everywhere?
Exactly.

>>  I was kind of under the impression I had to use "using namespace std;" in each *file*
Nope. Only where you want to import the namespace.

>>  In other words, the header files would not "pollute" the cpp files, as you say
They absolutely will and can result in some very hard to track down compiler time errors.

>> calling out the namespace is unnecessary in the cpp file if it is done in the header.
You should only have the using namespace clause in the .cpp file; NEVER the header.

"Namespace Rule #1: Avoid using directives entirely, especially in header files.

The reason for Rule #1 is that using directives cause wanton namespace pollution by bringing in potentially huge numbers of names, many (usually the vast majority) of which are unnecessary. The presence of the unnecessary names greatly increases the possibility of unintended name conflicts--not just in the header itself, but in every module that #includes the header. I find it helpful to think of a using directive as a marauding army of crazed barbarians that sows indiscriminate destruction wherever it passes--something that by its mere presence can cause "unintended conflicts," even when you think you're allied with it."

http://www.gotw.ca/publications/migrating_to_namespaces.htm

FWIW: GOTW is a very worthwhile read (it's quite large but full of very very helpful C++ tips).
NonComposMentisAuthor Commented:
Thanks, evilrix.  I read the entire page you referenced.  I like that they show you how to do all the stuff they're trying to talk you out of!  Very nice.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C++

From novice to tech pro — start learning today.