【问题标题】:C++ const char* overloading confusionC++ const char* 重载混淆
【发布时间】:2013-06-04 08:04:39
【问题描述】:

我不明白为什么这个程序会产生下面的输出。

void blah(const char* )       {printf("const char*\n");}
void blah(const std::string&) {printf("const string ref\n");}
template<class t>
void blah(t)                  {printf ("unknown\n");}

int main(int, char*)
{        
  blah("hi");
  char a[4];
  blah(a);
  std::string s;
  blah(s);
  getch();
}

输出:

const char*
unknown
const string

在 VS2008 中。它愿意将 std::string 转换为 const 引用,但为什么不将 char* 转换为 const char* 并使用重载?

【问题讨论】:

  • 它只是从您提供的选项中选择最接近的匹配项。 class t 可以完全匹配 char*,不需要转换,所以它会优先选择那个。
  • (顺便说一句,string 示例没有被转换为引用,而是默认通过引用传递,并且只有在没有匹配项时才会成为传递副本。模板不能改变引用性(右值引用的特殊情况除外),因此模板只能通过复制接受类)
  • 字符串“默认通过引用传递”是什么意思?为什么t 类型不能是std::string&amp;?让我明白的是,这两个电话都不是完全匹配的。 stringchar* 都不是 const
  • 正如我所说,“它默认通过引用传递,并且只有在没有匹配项时才会成为传递副本”。换句话说,它尝试string&amp; 然后const string&amp; then stringconst string。模板only 可以是后两种(因为“模板不能更改引用性”)。第一个不存在,所以第一个好的匹配是第二个。
  • 啊,我明白了,谢谢!

标签: c++ templates char constants overloading


【解决方案1】:

"hi" 的类型是const char[3],而a 的类型是char[4]

所以,第一次调用只需要数组到指针的转换(又名“衰减”)。第三个调用只需要将一个对象绑定到一个引用到常量(我不认为“转换”是引用绑定的正确术语,尽管我可能弄错了)。第二次调用需要数组衰减指针转换才能调用const char*重载。

我声称没有实际检查标准中的重载解决文本,这个额外的步骤使模板比const char* 重载更匹配。

顺便说一句,如果您将"unknown\n" 更改为"%s\n", typeid(t).name(),那么您可以看到t 的类型被推断为什么。对于您的代码,它被推断为char*(因为数组不能按值传递),但是看看如果您将模板更改为采用t&amp; 参数而不是t 会发生什么。那么t可以推导出为char[4]

【讨论】:

  • 这似乎不正确。 blah((char*)"hi") 仍然产生 unknown
  • @TysonJacobs 当然可以。正如blah((const char*)a) 将产生const char*explicit 转换发生在函数解析之前,因此函数调用必须将其转换为 back!
  • @Dave 但您的意思是模板匹配对blah("hi") 的调用,因为它必须将数组“衰减”为指针转换指针类型。投射到char* 消除了其中一个步骤。
  • @TysonJacobs 我们中的一个人很困惑。 blah("hi") 转到 const char*,而演员表将其更改为 unknown。这正是我和史蒂夫·杰索普提到的规则所期望的行为,所以我看不出问题……
  • @TysonJacobs: blah((char*)a) 需要指针转换才能调用 const char* 重载。因此,它选择模板的事实似乎与我的主张/猜测完全一致,即指针转换使const char* 重载比模板更差。数组衰减的有趣之处在于,虽然它是一种转换,但它不会导致更差的匹配。简而言之,不对称的原因是如果你从一个非常量数组或 ptr 开始,那么你需要一个指针转换来调用 const char* 重载。使用 const 数组则不需要。
猜你喜欢
  • 2021-11-18
  • 2020-03-04
  • 2013-01-25
  • 2018-06-13
  • 2017-09-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-11
相关资源
最近更新 更多