为什么在C++中使用关系运算符创建的模板函数不能对字符串正常工作?
Why does a Template function made using relational operator in C++ not work correctly for strings?
这是一个简单的代码,最多返回两个输入,以练习在C++中使用模板函数。代码将输出打印为"Hello",这是错误的,当我们取消注释行{string s = "Hello";}时,输出变得正确,即使使用的"Hello"不是s。 代码运行的屏幕截图
#include <iostream>
using namespace std;
template <typename T>
T maxx(T a, T b)
{
if (a>b) {return a;}
return b;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(NULL);
// string s = "Hello";
cout<<maxx("Hello","World")<<"n";
return 0;
}
由于此调用,模板函数的模板参数被推导为const char *
maxx("Hello","World")
因此,将比较指向字符串文本的第一个字符的指针。比较的结果取决于编译器在文本池中放置文本的顺序。
正如在另一个答案中已经说过的,maxx
函数作为参数const char *
,因此您比较指针,结果取决于编译器在数据部分中放置Hello
和World
的顺序。
那么,为什么当您取消注释string s = "Hello";
时顺序会发生变化?因为您在执行= "Hello"
时引入了另一个具有值Hello
const char *
,并且编译器将对maxx("Hello","World")
的其他Hello
使用相同的地址,因为这些常量字符不得更改,并且gcc
似乎从后到前评估maxx("Hello", "World")
的参数。
所以对于gcc
:
int main(){
ios::sync_with_stdio(false);
cin.tie(NULL);
// string s = "Hello";
cout<<maxx("Hello","World")<<"n";
return 0;
}
将导致:
.LC0:
.string "World"
.LC1:
.string "Hello"
.LC2:
.string "n"
main:
push rbp
mov rbp, rsp
mov edi, 0
call std::ios_base::sync_with_stdio(bool)
mov esi, 0
mov edi, OFFSET FLAT:_ZSt3cin+16
call std::basic_ios<char, std::char_traits<char> >::tie(std::basic_ostream<char, std::char_traits<char> >*)
mov esi, OFFSET FLAT:.LC0
mov edi, OFFSET FLAT:.LC1
call char const* maxx<char const*>(char const*, char const*)
mov rsi, rax
mov edi, OFFSET FLAT:_ZSt4cout
call std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)
mov esi, OFFSET FLAT:.LC2
mov rdi, rax
call std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)
mov eax, 0
pop rbp
ret
如果您现在取消注释string s = "Hello";
,将导致:
.LC0:
.string "Hello"
.LC1:
.string "World"
.LC2:
.string "n"
main:
…
由于在这种情况下,Hello
首先在string s = "Hello";
中找到,然后再计算maxx("Hello","World")
,因此在这种情况下,Hello
是添加到数据部分的第一个常量字符串,然后World
。
如果您在string s
之前添加string s2 = "World";
,则顺序将再次更改:
string s2 = "World";
string s = "Hello";
cout<<maxx("Hello","World")<<"n";
.LC0:
.string "World"
.LC1:
.string "Hello"
.LC2:
.string "n"
main:
…
相关文章:
- 为什么我不能在不创建字符串变量的情况下使用函数的字符串输出
- 为什么我不能将字符串::赋回字符串?
- 需要帮助在 c++ 中将字符串转换为字符 ----错误 "const char *" 类型的值不能用于初始化 "char" 类型的实体
- C++程序在将 int 与 cin 一起使用时有效,但不能使用字符串
- 不能在 if 语句 - c++ 中使用 void func 直接将字符串转换为大写
- 生成 constexpr 字符串表,不能产生常量表达式
- 为什么在C++中使用关系运算符创建的模板函数不能对字符串正常工作?
- C++ 不能在cout中使用向量和字符串文字
- 对于循环增量器不能用作字符串向量的索引
- 用C++替换std::字符串中的一个子字符串,但不能全部替换
- 为什么我们不能使用整数到字符串直接转换,但可以按位到字符串?
- C++ _beginthread不能将字符串作为参数传递
- 为什么我不能替换这样的字符串上的字符?
- Borland Builder 5 c++ 字符串不能在 0 处索引
- 使用boost multiprecision/mpfr float-字符串不能被解释为有效的整数错误
- 为什么两个不同的文本字符串不能替换为 = 运算符?
- 为什么包含'