- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试对我的 C++ 代码进行一些绑定(bind),并使用指向成员函数的指针。
我有以下代码:
class A
{
explicit A(float);
}
class B
{
void setA(A);
void setA(float);
}
然后我声明指向成员函数的指针:
(void (B::*)(A))&B::setA
(void (B::*)(float))&B::setA
编译器 (MSVC11) 发现第二行不明确。
如果我在类 B 中注释 setA(A),则编译器认为这两行都是正确的 (!)
这是编译器错误吗?
有没有办法在不修改 B 类签名的情况下规避这种情况?
编辑:
实际上,我发布的代码是从我的真实类中过度简化的,并且确实编译了..
这是一个真正重现错误的修改版本:
class A
{
public:
explicit A(float f=1.0f, float g=1.0f) {}
};
class B
{
public:
void setA(A){}
void setA(float f, float g=1.0f){}
};
与
(void (B::*)(A))&B::setA
(void (B::*)(float))&B::setA
(void (B::*)(float,float))&B::setA
第二行带来编译错误:错误 C2440:“类型转换”:无法将“重载函数”转换为“void (__thiscall B::*)(float)”
最佳答案
我会说这是一个错误。根据 C++11 标准的第 13.4/1 段:
A use of an overloaded function name without arguments is resolved in certain contexts to a function, a pointer to function or a pointer to member function for a specific function from the overload set. [...] . The function selected is the one whose type is identical to the function type of the target type required in the context. [...] The target can be
— an object or reference being initialized (8.5, 8.5.3),
— the left side of an assignment (5.17),
— a parameter of a function (5.2.2),
— a parameter of a user-defined operator (13.5),
— the return value of a function, operator function, or conversion (6.6.3),
— an explicit type conversion (5.2.3, 5.2.9, 5.4), or
— a non-type template-parameter (14.3.2).
由于很清楚重载集中的哪个成员函数具有与您显式转换到的成员函数相同的签名,因此您的代码是合法的。
此外,您的代码可以在 Clang 3.2、GCC 4.7.2、GCC 4.8、ICC 13.0.1 和 (!) VC10 上正常编译。参见,例如,this live example .
编辑:
您发布的新代码确实是非法的。
无法解析第二个转换,因为没有一个成员函数 setA()
只接受一个浮点参数。因此,编译器不知道表达式 &B::setA
指的是哪个函数。 .通常,它会尝试根据上下文显式转换来消除歧义,但这无济于事,因为它指定的签名与 setA()
的两个重载的签名不兼容。 .
如果您想知道为什么会这样以及为什么没有选择第二个重载,那么原因是带有默认参数的参数仍然是函数的形式参数(即使在某些调用中可以省略它) ),并且它的类型仍然算作函数签名的一部分。
另一方面,默认参数不是函数签名的一部分:
1.3.20 [defns.signature.member]
signature
<class member function>
name, parameter type list (8.3.5), class of which the function is a member, cv-qualifiers (if any), and ref-qualifier (if any)
现在,如果您删除重载 setA(A)
,编译器确实知道表达式&B::setA
是什么成员函数指,因为只有一个。无需使用显式转换来解析表达式。
然后,由于函数指针可以转换为其他类型的函数指针,因此编译器会执行额外的转换以指定目标类型。
关于c++ - 指向成员函数怪异的指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15959179/
C语言sscanf()函数:从字符串中读取指定格式的数据 头文件: ?
最近,我有一个关于工作预评估的问题,即使查询了每个功能的工作原理,我也不知道如何解决。这是一个伪代码。 下面是一个名为foo()的函数,该函数将被传递一个值并返回一个值。如果将以下值传递给foo函数,
CStr 函数 返回表达式,该表达式已被转换为 String 子类型的 Variant。 CStr(expression) expression 参数是任意有效的表达式。 说明 通常,可以
CSng 函数 返回表达式,该表达式已被转换为 Single 子类型的 Variant。 CSng(expression) expression 参数是任意有效的表达式。 说明 通常,可
CreateObject 函数 创建并返回对 Automation 对象的引用。 CreateObject(servername.typename [, location]) 参数 serv
Cos 函数 返回某个角的余弦值。 Cos(number) number 参数可以是任何将某个角表示为弧度的有效数值表达式。 说明 Cos 函数取某个角并返回直角三角形两边的比值。此比值是
CLng 函数 返回表达式,此表达式已被转换为 Long 子类型的 Variant。 CLng(expression) expression 参数是任意有效的表达式。 说明 通常,您可以使
CInt 函数 返回表达式,此表达式已被转换为 Integer 子类型的 Variant。 CInt(expression) expression 参数是任意有效的表达式。 说明 通常,可
Chr 函数 返回与指定的 ANSI 字符代码相对应的字符。 Chr(charcode) charcode 参数是可以标识字符的数字。 说明 从 0 到 31 的数字表示标准的不可打印的
CDbl 函数 返回表达式,此表达式已被转换为 Double 子类型的 Variant。 CDbl(expression) expression 参数是任意有效的表达式。 说明 通常,您可
CDate 函数 返回表达式,此表达式已被转换为 Date 子类型的 Variant。 CDate(date) date 参数是任意有效的日期表达式。 说明 IsDate 函数用于判断 d
CCur 函数 返回表达式,此表达式已被转换为 Currency 子类型的 Variant。 CCur(expression) expression 参数是任意有效的表达式。 说明 通常,
CByte 函数 返回表达式,此表达式已被转换为 Byte 子类型的 Variant。 CByte(expression) expression 参数是任意有效的表达式。 说明 通常,可以
CBool 函数 返回表达式,此表达式已转换为 Boolean 子类型的 Variant。 CBool(expression) expression 是任意有效的表达式。 说明 如果 ex
Atn 函数 返回数值的反正切值。 Atn(number) number 参数可以是任意有效的数值表达式。 说明 Atn 函数计算直角三角形两个边的比值 (number) 并返回对应角的弧
Asc 函数 返回与字符串的第一个字母对应的 ANSI 字符代码。 Asc(string) string 参数是任意有效的字符串表达式。如果 string 参数未包含字符,则将发生运行时错误。
Array 函数 返回包含数组的 Variant。 Array(arglist) arglist 参数是赋给包含在 Variant 中的数组元素的值的列表(用逗号分隔)。如果没有指定此参数,则
Abs 函数 返回数字的绝对值。 Abs(number) number 参数可以是任意有效的数值表达式。如果 number 包含 Null,则返回 Null;如果是未初始化变量,则返回 0。
FormatPercent 函数 返回表达式,此表达式已被格式化为尾随有 % 符号的百分比(乘以 100 )。 FormatPercent(expression[,NumDigitsAfterD
FormatNumber 函数 返回表达式,此表达式已被格式化为数值。 FormatNumber( expression [,NumDigitsAfterDecimal [,Inc
我是一名优秀的程序员,十分优秀!