我一直在寻找一种大写标准字符串的方法。我找到的答案包括以下代码:
int main()
{
// explicit cast needed to resolve ambiguity
std::transform(myString.begin(), myString.end(), myString.begin(),
(int(*)(int)) std::toupper)
}
有人能解释一下铸造表达式“(int(*)(int))”吗?我发现的所有其他演员示例和描述都只使用简单的类型转换表达式。
答案 0 :(得分:5)
它实际上是一个简单的类型转换 - 但是对于函数指针类型。
std::toupper
有两种风格。一个人需要int
并返回int
;另一个需要int
和const locale&
并返回int
。在这种情况下,它是第一个需要的,但编译器通常无法知道这一点。
(int(*)(int))
是对函数指针的强制转换,它接受int
(右手部分)并返回int
(左手部分)。只有toupper
的第一个版本可以像这样强制转换,因此它为编译器消除歧义。
答案 1 :(得分:3)
(int(*)(int))是函数指针类型的名称。该函数返回(int),是一个函数 * ,并带有一个(int)参数。
答案 2 :(得分:2)
int function(int);
一个功能int
并返回int
。
int (*function_pointer)(int);
指向int
并返回int
的函数的指针。
int (*)(int)
指向int
并返回int
的函数的指针类型。
std::toupper
的 <cctype>
已经有int (*)(int)
类型,但<locale>
中的charT
中的{{1}}被模板化,我认为这是投票的原因。但ptr_fun
会更清楚。
答案 3 :(得分:2)
正如其他人已经提到的,int (*)(int)
是指向函数的类型的指针,该函数接收并返回int
。但是这里缺少的是这个强制转换表达式的作用:与其他强制转换表达式不同,它不真正转换(即它不会将值转换为其他类型),但它选择来自名为std::toupper
的重载函数集,其中包含具有签名int(int)
的函数。
但请注意,此方法有点脆弱:如果由于某种原因没有匹配的函数(例如因为没有包含相应的标题)而只有一个不匹配的函数(因此不会出现歧义),那么这个演员表达式确实会转变为强制转换,更确切地说是reinterpret_cast
,具有不良影响。为了确保不会发生意外转换,应该使用C ++样式转换语法而不是C样式转换语法:static_cast<int(*)(int)>(std::toupper)
(实际上,在std::toupper
的情况下,这种情况不会发生,因为唯一的选择函数是模板化的,因此模糊不清,但是其他重载函数可能会发生这种情况。)
巧合的是,在这种情况下,新式演员合成器更具可读性。
另一种可能没有任何演员表达的可能性如下:
int (*ptoupper)(int) = &std::toupper; // here the context provides the required type information
std::transform(myString.begin(), myString.end(), myString.begin(), ptoupper);
请注意,上下文无法提供必要信息的原因是std::transform
是最后一个参数的模板,因此编译器无法确定要选择的正确函数。