重载指向函数的指针

时间:2016-10-24 11:17:38

标签: c++

我正在查看以下代码:

string toUpper(string s) {
    string result;
    int (*toupperp)(int) = &toupper; // toupper is overloaded
    transform(begin(s), end(s), back_inserter(result), toupperp);
    return result;
}

我对这一行感到困惑:

int (*toupperp)(int) = &toupper; // toupper is overloaded

1.为什么这条线是必要的?

2.我相信&从内存中检索指向某事物的指针。但toupper,函数的名称已经是指针,不是吗?为什么我们不能这样做:

int (*toupperp)(int) = toupper;

3.如果函数在int上使用,为什么会重载到string

2 个答案:

答案 0 :(得分:5)

1)真的没有必要。如果您使用了using namespace std指令,则必须将所需类型转换为let the compiler know which overload you want。所以,你也可以说

transform(begin(s), end(s), back_inserter(result), static_cast<int(*)(int)>(&toupper));

否则以下内容应该足够了:

transform(begin(s), end(s), back_inserter(result), ::toupper);

2)作为函数名称的标识符会衰减为指针,是的,但它们并不完全相同。话虽如此,在这种情况下应该没问题

int (*toupperp)(int) = toupper;

甚至(如果您还没有使用using namespace std指令):

auto toupperp = toupper; 

3)它与C标准库的兼容性。它用于s的每个元素,stringchar

答案 1 :(得分:4)

您传递给transform的内容是指向函数toupper的指针(请参阅function pointers)。将此指针存储到局部变量toupperp中。 toupperp的类型是指向以int为参数并返回int的函数的指针。

除非以奇怪的方式定义toupper,否则transform似乎使用该函数将每个输入字符更改为大写。每个单个字符都被处理为一个整数(如果需要,可以使用隐式转换)。

关于你的问题2,使用运算符&你更明确地表示你正在使用函数的地址,但实际上你可以省略它。见here(我今天学到了一些东西)。

如果toupper过载,使用中间变量是获得所需过载的安全方法。如果所需的重载消失,则此方法将在编译时捕获该问题。见here。 (这是我今天学到的其他东西)。