首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >悬挂指针/对int和char*常量的引用

悬挂指针/对int和char*常量的引用
EN

Stack Overflow用户
提问于 2019-04-22 16:13:32
回答 2查看 237关注 0票数 1

我正在读一本关于C++模板的书,这本书是由Vandevoorde,Josuttis和Gregor写的,但我不明白他们对悬空引用的警告。以下是代码:

代码语言:javascript
复制
#include <cstring>

// maximum of two values of any type (call-by-reference)
template<typename T>
T const& max (T const& a, T const& b)
{
  return  b < a ? a : b;
}

// maximum of two C-strings (call-by-value)
char const* max (char const* a, char const* b)
{
  return  std::strcmp(b,a) < 0  ? a : b;
}

// maximum of three values of any type (call-by-reference)
template<typename T>
T const& max (T const& a, T const& b, T const& c)
{
  return max (max(a,b), c);       // error if max(a,b) uses call-by-value
}

int main ()
{
  auto m1 = ::max(7, 42, 68);     // OK

  char const* s1 = "frederic";
  char const* s2 = "anica";
  char const* s3 = "lucas";
  auto m2 = ::max(s1, s2, s3);    // run-time ERROR
}

给出的消息是,对于C-字符串,嵌套的max(a,b)创建一个悬空引用,而对于int则不创建引用。那么,与int的引用相比,指针到char有什么特别之处,因为两者都是作为指向在max函数之外分配的对象的指针实现的?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-04-22 16:24:48

..。不明白他们对悬空引用的警告

::max(s1, s2, s3)使用template<typename T> T const& max (T const& a, T const& b, T const& c)返回引用

如果template<typename T> T const& max (T const& a, T const& b, T const& c)的定义更改为:

代码语言:javascript
复制
template<typename T>
T const& max (T const& a, T const& b, T const& c)
{
  return (a > b) ? ((a > c) ? a : c)
                 : ((b > c) ? b : c);
}

没有问题,因为它已经有参考资料。

但是对于::max(s1, s2, s3),T是const char*,所以在max (max(a,b), c) max中,char const* max (char const* a, char const* b)不返回引用,因为编译器将char const* max (char const* a, char const* b)的结果保存在堆栈上的临时变量中,并返回对该临时变量的引用,从而产生消息和相关的问题。这就像执行int & f() { int v = 0; return v; }一样,只是临时变量是由编译器本身创建的。

当然,这个问题在template<typename T> T const max (T const& a, T const& b, T const& c) (返回值而不是引用)中消失了,因为char const* max (char const* a, char const* b)返回的值可以直接返回。

注意,对于::max(7, 42, 68),没有问题,因为max (max(a,b), c)中的max是template<typename T> T const& max (T const& a, T const& b),它返回一个引用。

要继续返回另一种情况下的引用,可以为char *专门化max,例如:

代码语言:javascript
复制
// maximum of two C-strings (call-by-value)
template<>
char const* const & max (char const* const & a, char const* const & b)
{
  return  std::strcmp(b,a) < 0  ? a : b;
}

或者把它定义为

代码语言:javascript
复制
char const* const & max (char const* const & a, char const* const & b)
{
  return  std::strcmp(b,a) < 0  ? a : b;
}

它返回具有三个参数的版本可以使用的引用,而不必使用临时变量并返回对其的引用。

(就我个人而言,我更喜欢专业化,因为有模板版本似乎很自然)

代码语言:javascript
复制
#include <cstring>
#include <iostream>

// maximum of two values of any type (call-by-reference)
template<typename T>
T const& max (T const& a, T const& b)
{
  return  b < a ? a : b;
}

// MODIFIED
// maximum of two C-strings (call-by-value)
template<>
char const* const & max (char const* const & a, char const* const & b)
{
  return  std::strcmp(b,a) < 0  ? a : b;
}

// maximum of three values of any type (call-by-reference)
template<typename T>
T const& max (T const& a, T const& b, T const& c)
{
  return max (max(a,b), c);       // error if max(a,b) uses call-by-value
}

int main ()
{
  auto m1 = ::max(7, 42, 68);     // OK

  char const* s1 = "frederic";
  char const* s2 = "anica";
  char const* s3 = "lucas";
  auto m2 = ::max(s1, s2, s3);    // run-time ERROR

  std::cout << m2 << std::endl; // << ADDED TO CHECK
}

汇编和执行:

代码语言:javascript
复制
pi@raspberrypi:/tmp $ g++ -pedantic -Wall -Wextra s.cc
s.cc: In function ‘int main()’:
s.cc:28:8: warning: unused variable ‘m1’ [-Wunused-variable]
   auto m1 = ::max(7, 42, 68);     // OK
        ^~
pi@raspberrypi:/tmp $ ./a.out
lucas
票数 1
EN

Stack Overflow用户

发布于 2019-04-22 16:26:56

这是:

代码语言:javascript
复制
   char const* max (char const* a, char const* b)

返回一个无名的临时指针值,然后如下:

代码语言:javascript
复制
    return max (max(a,b), c);

返回对它的引用。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55797433

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档