Dangerous implicit conversion in emplace

The following code compiles without errors / warnings with gcc 6.3 ( https://godbolt.org/g/sVZ8OH ), but it contains dangerous undefined behavior due to invalid memory access, noted below. The main reason is the implicit conversion done in emplace_back. Can anyone suggest a good way or best practices to avoid such code errors?

#include <iostream> #include <vector> struct Foo { explicit Foo(const int& i) : i{i} {} void foo() const { std::cout << i; } // invalid memory access, as i is an invalid ref!! const int& i; }; void bar(const double& d) { std::vector<Foo> fv; fv.emplace_back(d); } 
+7
c ++ c ++ 11
source share
2 answers

If you intend to use a constant reference, but you do not want to refer to a temporary one, declare an additional constructor with the rvalue reference argument and delete it.

 struct Foo { explicit Foo(const int& i) : i{i} {} explicit Foo(const int&& i) = delete; // This preferentially matches a reference to a // temporary, and compilation fails. void foo() const { std::cout << i; } // invalid memory access, as i is an invalid ref!! const int& i; }; 

(I assume that the actual problem is more complicated than just int. For int, holding it by value is the correct answer.)

+11
source share

Can someone suggest a good way or best practices to avoid such code errors?

When your class stores a const link to another object, you, as a programmer, take the responsibility of making sure that you do not keep the link to hang out.

Unless you have a good reason to store a const link, I would recommend keeping the value.

 struct Foo { explicit Foo(const int& i) : i{i} {} void foo() const { std::cout << i; } int i; }; 
+4
source share

All Articles