variadic templates & pass by const reference & member operator [] in const map & gcc sucks

/// bugs code with comments
#include <iostream>
#include <memory>
#include <unordered_map>

using namespace std;

class A
{
public:
    A(const std::unordered_map<int, int > &ref) : ref_m(ref) {}

    void test1(int index) {
        // std::cout << ref_m[index] << std::endl; // bugs version in c++ specification, mainly sucks in gcc compile error prompts.
        std::cout << ref_m.at(index) << std::endl; // or ref_m.find() etc.
    }

    // this function will crash, as a result of ref_m get a wrong memory address by value passing instead of reference passing in gcc
    void test2() {
        for(auto& e: ref_m)
            std::cout << e.first << ‘ ‘<< e.second << std::endl;
    }

    void print_ref_size() {
        std::cout << "ref_m size: " <<  ref_m.size() << std::endl;
    }

private:
    const std::unordered_map<int, int >& ref_m;
};

template <typename ManipulatorType, typename ... Args>
std::shared_ptr<ManipulatorType> CreateTester(std::string name, Args ... args)
{
    return std::make_shared<ManipulatorType>(args ...);
}

class B{
public:
    B(){}

    std::shared_ptr<A> CreateATesterWrapper() {
        // return CreateTester<A>("uselessparams", ref); // bugs version in gcc
        return CreateTester<A>("uselessparams", std::ref(ref)); // or replace "Args ... args" with "Args& ... args"  in gcc
    }

    void print_ref_size() {
        std::cout << "ref size: " <<  ref.size() << std::endl;
    }

    std::unordered_map<int, int > ref = {{1,2}};
};

int main(int argc, char* argv[])
{
    B b;
    auto a = b.CreateATesterWrapper();
    b.print_ref_size();
    a->print_ref_size();
    a->test1(1);
    a->test2();
    return 0;
}

原文地址:https://www.cnblogs.com/xiconxi/p/10255240.html

时间: 2024-08-29 09:47:50

variadic templates & pass by const reference & member operator [] in const map & gcc sucks的相关文章

C++11 : variadic templates(可变参数模板)

Introduction: Before the possibilities of the new C++ language standard, C++11, the use of templates was quite limited when it came to implementing for instance function objects (functors) & tuple facilities. Implementing these sort of things using e

格式工厂(三) Variadic Templates

版权声明:本文为博主原创文章,未经博主允许不得转载. 这次主要介绍C++11的又一个新特性 Variadic Templates (可变模板参数) 它的实现类似于initializer_list<>,它可是使类模板接受一包参数 本节主要应用递归的形式介绍 Variadic  Templates 1.简单的调用 #include <iostream> #include "string" using namespace std; void printX() {}//

C 语言的 const 指针,指针的const有什么不同

Read it backwards (as driven by Clockwise/Spiral Rule)... int* - pointer to int int const * - pointer to const int int * const - const pointer to int int const * const - const pointer to const int Now the first const can be on either side of the type

const int *a和int *const a的区别

关键问题点:const 属于修饰符 ,关键是看const 修饰的位置在那里1.const int *a 这里const 修饰的是int,而int定义的是一个整值 因此*a 所指向的对象 值 不能通过 *a 来修改,但是 可以重新给 a 来赋值,使其指向不同的对象 eg:        const int *a = 0;        const int b = 1;        int c = 1;       a = &b  //  额外:注意不能通过a 来修改 b值       a = &a

static与const联合使用&amp;&amp;extern与const联合使用

static与const联合使用 static与const作用:声明一个只读的静态变量 开发使用场景:在一个文件中经常使用的字符串常量,可以使用static与const组合 extern与const联合使用 开发中使用场景:在多个文件中经常使用的同一个字符串常量,可以使用extern与const组合. 原因: static与const组合:在每个文件都需要定义一份静态全局变量. extern与const组合:只需要定义一份全局变量,多个文件共享. 全局常量正规写法:开发中便于管理所有的全局变量,

const修饰函数参数 const修饰函数返回值 const修饰成员函数

看到const 关键字,C++程序员首先想到的可能是const 常量.这可不是良好的条件反射.如果只知道用const 定义常量,那么相当于把火药仅用于制作鞭炮.const 更大的魅力是它可以修饰函数的参数.返回值,甚至函数的定义体. const 是constant 的缩写,"恒定不变"的意思.被const 修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性.所以很多C++程序设计书籍建议:"Use const whenever you need". 1

const char* &amp;p 和 char* const &amp;p 区别

const char* &p 和 char* const &p 两种引用: 两者都是对一个对象的引用. 但是前者的"这个对象"是 const char*,一个指向 const char 的指针,注意!虽 然这个指针指向的char不可以改变,但这个指针本身的值是可以改变的,也就是说, 他可以被改变而指向另一个 const char 对象. 后者的"这个对象"则是char*, 一个指向char的指针.这个指针指向的东西是可以 改变的,但是这个指针本身是不

const char *p 和char * const p

把一个声明从右向左读. char * const cp; ( * 读成 pointer to ) cp is a const pointer to char :const是修饰指针,表明指针不能修改指向了const char * p; p is a pointer to const char; :表明const是修饰一个只读变量,该内存位置是只读的,不可修改,p依旧可以指向别的地方 另外 #define是预处理指令,在编译预处理时进行简单的替换,不作正确性检查 typedef是在编译时处理的.它

const void *a 与 void *const a 的差别

const void *a 这是定义了一个指针a,a能够指向随意类型的值,但它指向的值必须是常量. 在这样的情况下,我们不能改动被指向的对象,但能够使指针指向其它对象. 比如: const void *a:*a=0x123;//是编译通只是的,由于*a中放的是个const值. const值是不能被改变的. const int  m=1;     const int n=2; a=&m;    a=&n;//编译能够通过. void* const  a 这是定义了一个const指针a.a能够