0

I wrote some basic code I learned that can be used to define a type that gets an enumerated value as its constructor argument and has a member function AsString() that returns the value as a string.

The code doesn't compile unless I include <iostream>. It displays a warning in main saying that the type color has not been declared. Why is it required to include an input/output header file in my code while no input/output functions or operators are used in it?

enum ColorEnum {blue, red};

class color
{
    protected:
        ColorEnum value;
    public:
        color(ColorEnum initvalue)
        {
            value = initvalue;
        }
        std::string AsString()
        {
            switch (value)
            {
                case blue:
                    return "blue";
                case red:
                    return "red";
                default:
                    return "N/A";
            }
        }
};

int main()
{
    color mycolor = blue;
    return 0;
}
Mo Sanei
  • 445
  • 6
  • 22
  • 2
    Is that ALL of your code, or did you remove something? You should have an include for at least, surely? – Mats Petersson Feb 07 '13 at 13:11
  • What did you also #include (provide full example, please), e.g. string is missing (where is ) – Beachwalker Feb 07 '13 at 13:12
  • By the way: I would recommend to start the class name color with an uppercase C => Color. It is also typical in the C++ world to use lowercase method names (except in some Microsoft APIs), AsString() would be named asString() by most developers (this is for C++, other languages has other conventions) or implement operators instead of the explicit conversion method. – Beachwalker Feb 07 '13 at 13:14
  • Why is it better to start with an uppercase letter? I've heard that many times, but I don't see the logic behind it. – Mo Sanei Feb 07 '13 at 13:18
  • 2
    @Beachwalker It is also typical in the C++ world to use a zillion of other different conventions. Don't let yourself be fooled by your bubble of experience. – R. Martinho Fernandes Feb 07 '13 at 13:25
  • @R.MartinhoFernandes ... was only a recommendation. Look how "most" people/books did it. Anyway you could also name your class cOlOr, but this does not increase readability. I would prefer code that is easy to read and follows a convention most other programmers use, too. I don't know what your bubble is - I can only speak for mine. (http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Naming, http://www.possibility.com/Cpp/CppCodingStandard.html) – Beachwalker Feb 07 '13 at 13:31
  • @Beachwalker Naming conventions are _personnal_. The only thing that matters is that everyone on your team follows the same convention. – Etienne de Martel Feb 07 '13 at 20:54

2 Answers2

7

You do not need <iostream>, you need <string> for std::string, which you may be getting indirectly via <iostream>.

juanchopanza
  • 223,364
  • 34
  • 402
  • 480
  • answered 18 secs ago Luchian Grigore, answered 18 secs ago juanchopanza lol :) – Luchian Grigore Feb 07 '13 at 13:12
  • @LuchianGrigore same answer too. But I think you beat me by a split second. – juanchopanza Feb 07 '13 at 13:13
  • 1
    And I wrote essentially the same thing in a comment :( – Mats Petersson Feb 07 '13 at 13:13
  • second, no. Milliseconds, maybe :) – Luchian Grigore Feb 07 '13 at 13:13
  • Does `` itself include ``? If yes, I guess that was my problem because I thought `` was only for input/output streaming. – Mo Sanei Feb 07 '13 at 13:22
  • @MohammadSanei it is not specified to include ``, and it doesn't in the compilers I use these days. But I have old memories of `` including strings on some compiler many years ago... Try including `` and see if it fixes the problem. – juanchopanza Feb 07 '13 at 13:24
  • It did fix the problem, thanks. You mean in newer compilers I must include both `` and `using namespace std` just to be able to declare a string variable? – Mo Sanei Feb 07 '13 at 13:28
  • 1
    @MohammadSanei You have to `#include `, but you shouldn't `use namespace std`. Just call it `std::string`. – juanchopanza Feb 07 '13 at 13:29
  • 1
    @MohammadSanei more on `using namespace std` [here](http://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-a-bad-practice-in-c). – juanchopanza Feb 07 '13 at 13:31
  • Thanks. I think my `` includes the `` file. But it's weird I don't see the line `#include ` when I look inside my ``. – Mo Sanei Feb 07 '13 at 13:39
  • @MohammadSanei: MSVC's `iostream` includes a header that has `std::string` defined in it, but does not actually include the `string` header itself. Many consider this a poor decision on Microsoft's part. – Mooing Duck Feb 07 '13 at 20:52
  • @MooingDuck That's not the case with my compiler which is CodeBlocks because I always need to add `std::` to my string types whether I include `` or ``. My `` seems to include `` rather than define `std::string`. But I don't see the inclusion statement anywhere in the `` file or its include files. – Mo Sanei Feb 07 '13 at 21:41
  • 1
    No matter what header you include, you should always have to type `std::`. `iostream` needs to define `std::string` to work, period. However, it doesn't have to do that by including the `string` header directly. In MSVC, `std::string` is defined in the `xstring` header, which both the `string` header and `iostream` include. (Your header names will differ since you're using codeblocks) – Mooing Duck Feb 07 '13 at 21:56
5

You don't need to include <iostream>, but <string>, because you use std::string, so that might set the compiler off.

If you include <string> and still get the error, that sounds like a bug in the compiler.

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
  • OK, we'll need a cage to determine which answer wins. – Mike DeSimone Feb 07 '13 at 13:13
  • More specifically, there should also be another error complaining about a missing definition for `std::string` - or, more likely still, the compiler will have complained about an "incomplete type" instead of an "undefined type" – Magnus Feb 07 '13 at 13:13