Reputation: 33
I have the following code.
void print_pair(const std::pair<const std::string&, const int&>& p)
{
std::cout << p.first << "," << p.second << std::endl;
}
print_pair(std::pair<const std::string&, const int&>("test",1));//1
print_pair(std::pair<const std::string&, const int&>(std::string("test"),1));//2
which produces the following output:
,1
test,1
shouldn't the two lines produce the same output, as in the first case the constructor for string from char* should be implicitly called? why does const reference not seem to prolong the life of first pair argument in the first case?
it is compiled with gcc4.9 -std=c++11 -O3.
Upvotes: 3
Views: 77
Reputation: 208446
The problem is that your pair is a pair of references, not values. When you have:
using pair_t = std::pair<const std::string&, const int&>;
pair_t("test",1);
The compiler needs to find the best candidate for the construction, the best match in C++11 is:
template< class U1, class U2 >
constexpr pair( U1&& x, U2&& y );
Where the types are U1 = const char(&)[5]
and U2 = int
. Internally, to bind the reference it is going to create a temporary string, but when that expression completes (and before returning from that constructor), the temporary will go away and you will be left with a dangling reference.
The program has undefined behavior, and it prints an empty string in the same way that it could have crashed or print any garbage.
In the case where you do:
pair_t(std::string("test"), 1);
The expression in which the temporary is created is the same expression that calls the function, and the lifetime of that temporary will last until the function completes, so that second line is correct and exhibits the expected behavior.
Upvotes: 8