【问题标题】:constructor of string from char* not implicitly called?char* 中的字符串构造函数没有被隐式调用?
【发布时间】:2015-03-21 03:28:46
【问题描述】:

我有以下代码。

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

产生以下输出:

,1
test,1

这两行不应该产生相同的输出吗,因为在第一种情况下,应该隐式调用 char* 中的字符串的构造函数?为什么 const 引用在第一种情况下似乎没有延长第一对参数的寿命?

使用 gcc4.9 -std=c++11 -O3 编译。

【问题讨论】:

  • 尝试从std::string中删除&amp;...
  • @zenith:你已经在 C++03 模式下构建,构造函数的最佳匹配是std::pair&lt;std::string const&amp;, int const&amp;&gt;(std::string const &amp;, int const &amp;)。在 C++11 之前,临时字符串将由调用者创建,并且会比函数调用更有效。如果您在 C++11 或 C++14 模式下重新运行该代码,您将获得未定义的行为。

标签: c++


【解决方案1】:

问题在于您的对是一对引用,而不是值。当你有:

using pair_t = std::pair<const std::string&, const int&>;
pair_t("test",1);

编译器需要为构造找到最佳候选,C++11中的最佳匹配是:

template< class U1, class U2 >
constexpr pair( U1&& x, U2&& y );

类型为U1 = const char(&amp;)[5]U2 = int。在内部,要绑定引用,它将创建一个临时字符串,但是当该表达式完成时(并且在从该构造函数返回之前),临时将消失,您将留下一个悬空引用。

程序有未定义的行为,它打印一个空字符串,就像它可能崩溃或打印任何垃圾一样。

如果你这样做:

pair_t(std::string("test"), 1);

创建临时的表达式与调用函数的表达式相同,并且该临时的生命周期将持续到函数完成,因此第二行是正确的并表现出预期的行为。

【讨论】:

  • 我在初读时没有明白这一点。因此在二读后赞成。这是标准中一个非常微妙的重大更改。据我所知,它没有列在兼容性部分。
  • 是字符串文字的左值,因此 U1 应该是 char[5]&?
  • @swang:是的,我没有注意那个细节,推断的类型是const char (&amp;)[5]
猜你喜欢
  • 1970-01-01
  • 2015-02-09
  • 2014-07-26
  • 2016-07-12
  • 2018-06-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多