variadic templates & pass by const reference & member operator [] in const map & gcc sucks
阿新 • • 發佈:2019-01-11
/// 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; }