类内的c ++全局地图,请勿打印地图元素。使用cmake

时间:2018-09-13 21:15:16

标签: c++ c++11 stdmap c++03

我试图在类a中定义一个全局映射,然后在类b中使用它。 尽管map不是空的,但我看不到元素。

另一个困扰我的问题是,我怎么知道我的代码是否使用c ++ 11标准编译? 如何设置它以与c ++ 98或C ++ 2003一起编译?

我有5个文件:

  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();
    }
    

现在,我正在使用cmake编译ubuntu 17.10.1下的代码。

CMakeLists.txt是

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)

在调用cmake ../build(build是我的构建目录)之后,我正在调用make,编译的代码没有错误。

但是我的输出是第一对为空,尽管地图上有元素。

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

怎么了? 谢谢。

2 个答案:

答案 0 :(得分:1)

std::uint8_t很可能是unsigned char的typedef。并且,当您向char提供unsigned charsigned charstd::ostream时,它会将其视为数字而不是数字。因此,您的程序不是打印数字八进制010 /十进制8,而是打印以该数字作为代码的字符。假设您的字符集是ASCII的某种扩展,则这是不可打印的字符“退格”,因此您的终端可能会忽略它。

要将std::uint8_t打印为数字,请在unsigned int上添加显式强制转换:

cout << "global map first pair=" << static_cast<unsigned int>(map_global["1"]) << endl;

答案 1 :(得分:0)

让我回答您的第二个问题。您可以将以下语句添加到CMakeLists.txt文件中,以强制编译器使用C ++ 11标准

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")

其他标准设置如下:

  1. -std = c ++ 98或-std = c ++ 03 ----- C ++ 98(C ++ 2003)
  2. -std = c ++ 11 ----- C ++ 11
  3. -std = c ++ 14 ----- C ++ 14
  4. -std = c ++ 17或-std = c ++ 1z ----- C ++ 17
  5. -std = gnu ++ 98 ----- C ++ 98和GNU扩展
  6. -std = gnu ++ 11 ----- C ++ 11和GNU扩展
  7. -std = gnu ++ 14 ----- C ++ 14和GNU扩展
  8. -std = gnu ++ 1z ----- C ++ 17和GNU扩展

对于默认标准,这取决于您使用的是哪个编译器以及编译器的版本。我认为最好使用上述方法来阐明C ++标准。

您可以在CMakeLists.txt中使用以下语句来测试编译器支持的标准并进行设置。

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()