[try Beta version]
Not logged in

 
Enum and Namespace mystery

Sep 22, 2014 at 3:57pm
Hi Friends,

Am trying to work with enum + namespaces combined, I landed into some confusing problems, your clear explanation will help me understand this concept very well.

a) My namespaces header file:
1
2
3
4
5
6
7
8
9
10
11
//namespaces.h

namespace san{

    void say_hi(){
        std::cout<<"Hi there !"<<std::endl ;
    }
    typedef enum{
        Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday
    } Week ;
}


b) My main program file:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
//First_go.cpp

#include <iostream>
#include "namespaces.h"

int main(int argC, char *argV[]){

    san::say_hi() ;
    san::Week Today ;
    Today = san::Week::Monday ;
    std::cout<<"Today = "<<Today<<std::endl ;

    return 0 ;
}


c) Output Error:
1
2
3
4
g++ -o First_go ./First_go.cpp
./First_go.cpp: In function ‘int main(int, char**)’:
./First_go.cpp:8:18: error: ‘san::Week’ is not a class or namespace
Today = san::Week::Monday ;


Am just expecting it to print 0, since Monday is 0 right ??
Many thanks in advance :)

Cheers,
San
Sep 22, 2014 at 4:00pm
C-style Unscoped enums place their elements into the enclosing namespace. C++ scoped enums create their own namespace.

http://en.cppreference.com/w/cpp/language/enum#Scoped_enumerations.28since_C.2B.2B11.29
Last edited on Sep 22, 2014 at 8:11pm
Sep 22, 2014 at 4:18pm
Hi thanks, So I cannot place enum inside a namespace ? san::Week::Monday doesn't work...

Sep 22, 2014 at 5:10pm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
namespace san{

    enum class week { // scoped enum
        Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday
    };

    enum colour { // unscoped enum
        Red, Green, Blue, Black, Grey, White
    };
}

int main()
{
    san::week today = san::week::Monday ; // scoped enum

    san::colour cloudy = san::Grey ; // unscoped enum
}


Note: A C++ unscoped enum is not a C-style enum. There is no C-style enum in C++.
Sep 22, 2014 at 8:11pm
Sorry, I used the term "C-style" because their behavior comes from C. I won't use that term to refer to unscoped enums again.
Sep 23, 2014 at 12:42pm
Awesome, thanks it worked with -std=c++11 option but cout dint work:

std::cout<<"Today = "<<Today<<std::endl ;

even I tried to cast it:

std::cout<<"Today = "<<static_cast<std::string>(Today)<<std::endl ;

Error:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
g++ -o First_go ./First_go.cpp -std=c++11
./First_go.cpp: In function ‘int main(int, char**)’:
./First_go.cpp:10:58: error: no matching function for call to ‘std::basic_string<char>::basic_string(san::Week&)’
std::cout<<"Today = "<<static_cast<std::string>(Today)<<std::endl ;
^
./First_go.cpp:10:58: note: candidates are:
In file included from /usr/include/c++/4.8/string:52:0,
from /usr/include/c++/4.8/bits/locale_classes.h:40,
from /usr/include/c++/4.8/bits/ios_base.h:41,
from /usr/include/c++/4.8/ios:42,
from /usr/include/c++/4.8/ostream:38,
from /usr/include/c++/4.8/iostream:39,
from ./First_go.cpp:3:
/usr/include/c++/4.8/bits/basic_string.h:532:9: note: template<class _InputIterator> std::basic_string<_CharT, _Traits, _Alloc>::basic_string(_InputIterator, _InputIterator, const _Alloc&)
basic_string(_InputIterator __beg, _InputIterator __end,
^
/usr/include/c++/4.8/bits/basic_string.h:532:9: note: template argument deduction/substitution failed:
./First_go.cpp:10:58: note: candidate expects 3 arguments, 1 provided
std::cout<<"Today = "<<static_cast<std::string>(Today)<<std::endl ;
^
In file included from /usr/include/c++/4.8/string:52:0,
from /usr/include/c++/4.8/bits/locale_classes.h:40,
from /usr/include/c++/4.8/bits/ios_base.h:41,
from /usr/include/c++/4.8/ios:42,
from /usr/include/c++/4.8/ostream:38,
from /usr/include/c++/4.8/iostream:39,
from ./First_go.cpp:3:
/usr/include/c++/4.8/bits/basic_string.h:522:7: note: std::basic_string<_CharT, _Traits, _Alloc>::basic_string(std::initializer_list<_Tp>, const _Alloc&) [with _CharT = char; _Traits = std::char_traits<char
>; _Alloc = std::allocator<char>]
basic_string(initializer_list<_CharT> __l, const _Alloc& __a = _Alloc());
^
/usr/include/c++/4.8/bits/basic_string.h:522:7: note: no known conversion for argument 1 from ‘san::Week’ to ‘std::initializer_list<char>’
/usr/include/c++/4.8/bits/basic_string.h:507:7: note: std::basic_string<_CharT, _Traits, _Alloc>::basic_string(std::basic_string<_CharT, _Traits, _Alloc>&&) [with _CharT = char; _Traits = std::char_traits<c
har>; _Alloc = std::allocator<char>]
basic_string(basic_string&& __str) noexcept
^
/usr/include/c++/4.8/bits/basic_string.h:507:7: note: no known conversion for argument 1 from ‘san::Week’ to ‘std::basic_string<char>&&’
/usr/include/c++/4.8/bits/basic_string.h:497:7: note: std::basic_string<_CharT, _Traits, _Alloc>::basic_string(std::basic_string<_CharT, _Traits, _Alloc>::size_type, _CharT, const _Alloc&) [with _CharT = ch
ar; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>; std::basic_string<_CharT, _Traits, _Alloc>::size_type = long unsigned int]
basic_string(size_type __n, _CharT __c, const _Alloc& __a = _Alloc());
^
/usr/include/c++/4.8/bits/basic_string.h:497:7: note: candidate expects 3 arguments, 1 provided
/usr/include/c++/4.8/bits/basic_string.h:490:7: note: std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const _CharT*, const _Alloc&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = s
td::allocator<char>]
basic_string(const _CharT* __s, const _Alloc& __a = _Alloc());
^
/usr/include/c++/4.8/bits/basic_string.h:490:7: note: no known conversion for argument 1 from ‘san::Week’ to ‘const char*’
/usr/include/c++/4.8/bits/basic_string.h:483:7: note: std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const _CharT*, std::basic_string<_CharT, _Traits, _Alloc>::size_type, const _Alloc&) [with _Cha
rT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>; std::basic_string<_CharT, _Traits, _Alloc>::size_type = long unsigned int]
basic_string(const _CharT* __s, size_type __n,
^
/usr/include/c++/4.8/bits/basic_string.h:483:7: note: candidate expects 3 arguments, 1 provided
/usr/include/c++/4.8/bits/basic_string.h:471:7: note: std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const std::basic_string<_CharT, _Traits, _Alloc>&, std::basic_string<_CharT, _Traits, _Alloc>::
size_type, std::basic_string<_CharT, _Traits, _Alloc>::size_type, const _Alloc&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>; std::basic_string<_CharT, _Traits, _All
oc>::size_type = long unsigned int]
basic_string(const basic_string& __str, size_type __pos,
^
/usr/include/c++/4.8/bits/basic_string.h:471:7: note: candidate expects 4 arguments, 1 provided
/usr/include/c++/4.8/bits/basic_string.h:462:7: note: std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const std::basic_string<_CharT, _Traits, _Alloc>&, std::basic_string<_CharT, _Traits, _Alloc>::
size_type, std::basic_string<_CharT, _Traits, _Alloc>::size_type) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>; std::basic_string<_CharT, _Traits, _Alloc>::size_type
= long unsigned int]
basic_string(const basic_string& __str, size_type __pos,
^
/usr/include/c++/4.8/bits/basic_string.h:462:7: note: candidate expects 3 arguments, 1 provided
/usr/include/c++/4.8/bits/basic_string.h:455:7: note: std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const std::basic_string<_CharT, _Traits, _Alloc>&) [with _CharT = char; _Traits = std::char_tra
its<char>; _Alloc = std::allocator<char>]
basic_string(const basic_string& __str);
^
/usr/include/c++/4.8/bits/basic_string.h:455:7: note: no known conversion for argument 1 from ‘san::Week’ to ‘const std::basic_string<char>&’
/usr/include/c++/4.8/bits/basic_string.h:448:7: note: std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const _Alloc&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<c
har>]
basic_string(const _Alloc& __a);
^
/usr/include/c++/4.8/bits/basic_string.h:448:7: note: no known conversion for argument 1 from ‘san::Week’ to ‘const std::allocator<char>&’
/usr/include/c++/4.8/bits/basic_string.h:437:7: note: std::basic_string<_CharT, _Traits, _Alloc>::basic_string() [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]
basic_string()
^
/usr/include/c++/4.8/bits/basic_string.h:437:7: 
Last edited on Sep 23, 2014 at 12:45pm
Sep 23, 2014 at 1:12pm
Enums have never been convertible to strings in C++. You need to provide your own helper function for that.
Sep 23, 2014 at 4:43pm
The underlying type of an enum is an integral type.
An enum can be converted to its underlying integral type (explicitly for scoped enums).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include <iostream>

namespace san {

    enum class week { // scoped enum
        Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday
    };

    enum colour { // unscoped enum
        Red, Green, Blue, Black, Grey, White
    };
}

namespace san2 {

    enum class week { // scoped enum
        Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday
    };
    std::ostream& operator<< ( std::ostream& stm, week w )
    {
        static const char* const names[] = {
            "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday", "Undefined"
        };
        std::size_t pos = std::size_t(w) ;
        if( pos > std::size_t(week::Sunday) ) pos = std::size_t(week::Sunday) + 1 ;
        return stm << names[pos] ;
    }

    enum colour { // unscoped enum
        Red, Green, Blue, Black, Grey, White
    };
    std::ostream& operator<< ( std::ostream& stm, colour c )
    {
        static const char* const names[] = {
            "Red", "Green", "Blue", "Black", "Grey", "White", "Undefined"
        };

        std::size_t pos = c ;
        if( pos > White ) pos = White + 1 ;
        return stm << names[pos] ;
    }
}

int main()
{
    {
        san::week today = san::week::Tuesday ;
        std::cout << int(today) << '\n' ; // 1
        // explicit conversion to int

        san::colour cloudy = san::Grey ;
        std::cout << cloudy << '\n' ; // 4
        // implicit conversion (promotion) to int
    }
    {
        san2::week today = san2::week::Tuesday ;
        std::cout << today << '\n' ; // Tuesday

        san2::colour cloudy = san2::Grey ;
        std::cout << cloudy << '\n' ; // Grey
    }
}

http://coliru.stacked-crooked.com/a/2ec9e1445d2eb779
Sep 25, 2014 at 10:09am
Omg amazing, thanks a million JLBorges... Gosh its so intimidating... Dono if I can be a good C++ Programmer like you
Topic archived. No new replies allowed.