1

I am trying to define a global map within a class a, then use it in class b. although map is not empty, I could not see the elements.

another issue that bother me is, how do I know if my code compiled using c++11 standard? How can I set it, to compile with c++98 or C++2003 ?

I have 5 files:

  1. map_user_a.h

    #include <map>
    #include <string>
    #include <stdint.h>
    
    using namespace std;
    
    extern std::map<string, uint8_t> map_global;
    
    class map_user_a
    {
        public: 
            void init();
        private:
            int user_a;
    };
    
  2. map_user_a.cpp

    #include <iostream>
    #include "map_user_a.h"
    std::map<string, uint8_t> map_global;
    void map_user_a::init()
    {
        std::cout<<"map_user_a::init()"<<endl;
    
        map_global.insert(std::make_pair("1", 010));
        map_global.insert(std::make_pair("2", 020));
    }
    
  3. map_user_b.h

    #include <map>
    #include <string>
    #include <stdint.h> 
    
    using namespace std;
    
    extern std::map<string, uint8_t> map_global;
    
    class map_user_b
    {
        public:
            void use();
        private:
            int user_b;
    };
    
  4. map_user_b.cpp

    #include <iostream>
    #include "map_user_b.h"
    
    using namespace std;
    
    void map_user_b::use()
    {
        cout<<"map_user_b::use()"<<endl;
        cout<<"global map first pair="<< map_global["1"] <<endl;
    }
    
  5. main.cpp

    #include "map_user_a.h"
    #include "map_user_b.h"
    
    main()
    {
    
        map_user_a map_a;
        map_a.init();
    
        map_user_b map_b;
        map_b.use();
    }
    

Now, I am compile the code under ubuntu 17.10.1 using cmake.

CMakeLists.txt is

cmake_minimum_required(VERSION 3.9)

project (stl)

add_executable(stl map_user_a.cpp map_user_a.h map_user_b.cpp map_user_b.h main.cpp)

after call to cmake ../build (build is my build directory) I am calling to make, the code compiled with no errors.

But my output is first pair empty although the map has element.

map_user_a::init()
map_user_b::use()
global map first pair=

what is wrong ? Thanks.

progtec
  • 61
  • 1
  • 4
  • Please avoid asking unrelated questions in the same SO question. But you may be interested in this Q&A about setting C++ language version in CMake: https://stackoverflow.com/questions/10851247/how-to-activate-c-11-in-cmake – aschepler Sep 13 '18 at 21:21
  • 1
    It is not valid to omit the return type from any function: `main()` should be `int main()`. Writing `using namespace std;` at global scope, and especially in a header file, is Considered Harmful: see https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice – aschepler Sep 13 '18 at 21:32
  • Not related ... my makefile generates the following command: g++ -O3 -ggdb -std=c++17 -Wall -Wextra -Wshadow -Wnon-virtual-dtor -pedantic -Werror=vla -Wcast-align -Wcast-qual -Wconversion -Wpointer-arith -Wunused -Wold-style-cast -Woverloaded-virtual -MMD -MP -O0 ../../bag/src/dtb_assert.o GameOfLife.cc -o GameOfLife -lncurses -pthread – 2785528 Sep 13 '18 at 21:50

2 Answers2

1

std::uint8_t is most likely a typedef for unsigned char. And when you supply a char, unsigned char, or signed char to a std::ostream, it treats it not as a number but as a character. So your program is printing not the number octal 010 / decimal 8, but the character with that number as its code. Assuming your character set is some extension of ASCII, this is the unprintable character "backspace", so your terminal probably just ignores it.

To print a std::uint8_t as a number, add an explicit cast to unsigned int:

cout << "global map first pair=" << static_cast<unsigned int>(map_global["1"]) << endl;
aschepler
  • 70,891
  • 9
  • 107
  • 161
0

Let me answer your second question. You can add the following statements to the CMakeLists.txt file to force the compiler to use the C++11 standard

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -std=c++11")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -std=c++11")

The other standard settings are as follows:

  1. -std=c++98, or -std=c++03 ----- C++98(C++2003)
  2. -std=c++11 ----- C++11
  3. -std=c++14 ----- C++14
  4. -std=c++17 or -std=c++1z ----- C++17
  5. -std=gnu++98 ----- C++98 and GNU extensions
  6. -std=gnu++11 ----- C++11 and GNU extensions
  7. -std=gnu++14 ----- C++14 and GNU extensions
  8. -std=gnu++1z ----- C++17 and GNU extensions

As for the default standard, it depends on which compiler you are using and the version of the compiler.I think it is better to use the above method to clarify the C++ standard.

You can use the following statement in CMakeLists.txt to test the standards supported by the compiler and set it up.

include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
CHECK_CXX_COMPILER_FLAG("-std=c++14" COMPILER_SUPPORTS_CXX14)
CHECK_CXX_COMPILER_FLAG("-std=c++17" COMPILER_SUPPORTS_CXX17)
if(COMPILER_SUPPORTS_CXX17)
    message(STATUS "support c++17")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17")
elseif(COMPILER_SUPPORTS_CXX14)
    message(STATUS "support c++14")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14")
elseif(COMPILER_SUPPORTS_CXX11)
    message(STATUS "support c++11")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
endif()
eprom
  • 226
  • 2
  • 11