CppQuiz系列 2

字符串类型,参数匹配

#include <iostream>
#include <string>

void f(const std::string &) { std::cout << 1; }

void f(const void *) { std::cout << 2; }

int main() {
  f("foo");
  const char *bar = "bar";
  f(bar);
}

答案是:22

字符串字面值不是std::string类型,而是const char[]类型。如果编译器要调用第一个函数声明的话,它会去找是否有用户定义的转换函数,然后创建一个临时的std::string对象。然而它更倾向于调用f(const void *),因为是一个array-to-pointer conversion。

A string literal is not a std::string, but a const char[]. If the compiler was to choose f(const std::string&), it would have to go through a user defined conversion and create a temporary std::string. Instead, it prefers f(const void*), which requires no user defined conversion.

好,问题来了,如果我再加几个定义呢?

template <class T>
void f(T &s) { std::cout << 3; }
template <int N>
void f(const char (&)[N]) { std::cout << 4; }

是不是感觉大脑要爆炸?

答案是:43,同样的,解析在下一期给出。


接上期,为什么f(42)会出错呢?

因为参数为int,模板实例化时会推断Tint,所以函数声明为void f(int&),而intint&不匹配,所以会CE。

那有人会问了,那为什么字面值不能和const int &匹配呢,字面值是可以绑定到const &上的,然而,偏特化的函数版本void f(const int &)Tconst int ,而调用时T推导为int,不匹配。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值