【问题标题】:why is 'Hello' being printed out when it is compared with 'World' in cpp?为什么在cpp中与'World'比较时会打印出'Hello'?
【发布时间】:2020-05-17 10:59:43
【问题描述】:

我在 CPP 中尝试使用模板。当我将它与 'World' 进行比较时,我无法理解为什么会打印 'Hello'?

下面是我的代码 sn-p ->

#include <iostream>
using std::cout;
using std::endl;

template <typename T>
T max(T a, T b){
if(a > b){
return a;
}
else{return b;}
}

int main() {
  cout << "max(3, 5): " << max(3, 5) << endl;
  cout << "max('a', 'd'): " << max('a', 'd') << endl;
  cout << "max(\"Hello\", \"World\"): " << max("Hello", "World") << endl;
  return 0;
}

输出

ec2-user:~/environment/cpp_learn/uiuc_cpp/cpp-templates (master) $ make
g++ -std=c++14 -O0 -pedantic -Wall  -Wfatal-errors -Wextra  -MMD -MP -g -c  main.cpp -o .objs/main.o
g++ .objs/main.o -std=c++14  -o main
ec2-user:~/environment/cpp_learn/uiuc_cpp/cpp-templates (master) $ ./main 
max(3, 5): 5
max('a', 'd'): d
max("Hello", "World"): Hello

这是我使用的 C++ 版本 ->

ec2-user:~/environment/cpp_learn/uiuc_cpp/cpp-templates (master) $ c++ --version
c++ (GCC) 7.2.1 20170915 (Red Hat 7.2.1-2)
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

提前感谢您的帮助。如果答案太明显,我很抱歉。

【问题讨论】:

  • 因为指针恰好比另一个大。您不是在比较字符串的内容,而是在比较指针。
  • 如果正在比较指针,那么我可以使用取消引用符号“*”来比较实际值吗?像 - if(*a > *b){ return a; }
  • 你可以,但是你只会比较第一个字符,这可能不是你想要的

标签: c++ string-comparison


【解决方案1】:

"Hello""World" 都是 c 风格的字符串(类型为 const char[6]),当被传递给 max 时,它们会衰减为 const char*,并且 T 也被推导出为 const char*。所以比较只是比较指针,即内存地址,reuslt是unspecified

您可以使用 strcmp 添加重载或模板特化来比较 c 风格的字符串,或者改用 std::string

my_max(std::string("Hello"), std::string("World")) // name changed because of the conflict with std::max 

【讨论】:

  • 感谢您的回复。我不明白为什么'Hello'的内存地址总是大于'World'而'a'的内存地址总是小于'd'?我也尝试过先通过“世界”,但输出仍然相同。
  • 另外,我尝试了您的更改。它给出了编译器错误 - main.cpp:23:90: 错误:重载 'max(std::string, std::string)' 的调用不明确 cout
  • @HARSHITBAJPAI 对于chars,比较值(不是成员地址),因此返回'd'。像这种情况比较成员地址的结果是不确定的。
  • @HARSHITBAJPAI 关于编译错误,名称与std::max冲突。改个名字就好了。 LIVE
【解决方案2】:

相反,您可以使用两个模板 TP 来做同样的事情。

#include <iostream>
#include <string>
using std::cout;
using std::endl;
using std::string;
template <typename T,typename P>
T max(T a, P b){
if(a > b){
return a;
}
else{return b;}
}

int main() {
  cout << "max(3, 5): " << max(3, 5) << endl;
  cout << "max('a', 'd'): " << max('a', 'd') << endl;
  cout << "max(\"Hello\", \"World\"): " << max(string("Hello"),string("World")) << endl;
  return 0;
}

编译这个修改后的版本。 这段代码是不言自明的。

【讨论】:

  • 谢谢。为什么要使用 2 个类型名?
  • @HARSHITBAJPAI 如果您想使用名称max,因为它与内置的最大值冲突。当我们必须使用多种数据类型(如sum(string("10.5"),'c'))时,使用两个类型名称很有用,如果我们使用相同的模板,这将不起作用。
猜你喜欢
  • 2020-02-03
  • 2015-12-04
  • 2011-09-12
  • 1970-01-01
  • 1970-01-01
  • 2019-03-19
  • 2018-10-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多