C++ 重载解析、转换运算符和 const
C++ overload resolution, conversion operators and const
在这种情况下
void f(int *);
void f(const int *);
...
int i;
f(&i);
情况很清楚 - f(int *) 被调用,这似乎是正确的。
但是,如果我有这个(这是错误的(*)):
class aa
{
public:
operator bool() const;
operator char *();
};
void func(bool);
aa a;
func(a);
operator char *() 被调用。我不明白为什么这样的决策路径会比使用 operator bool() 更好。有什么想法吗?
(*) 如果将 const 添加到第二个运算符,代码当然会按预期工作。
a
是 aa
的非常量实例,因此非常量转换运算符比 const 运算符(需要添加常量)更好(精确)匹配,即使 return 类型也不匹配。
您的 "aa" 对象不是 const,因此 C++ 更喜欢非常量转换。
如果将 "aa" 设为常量,则将使用 const bool() 转换运算符。
因为对于使用转换运算符的用户定义转换,返回类型到目标类型(即 char*
到 bool
)的转换被认为是 在 [=29 之后=] 对象参数转换,即对象参数a
到隐式对象参数的转换。 [over.match.best]/1:
Given these definitions, a viable function F1
is defined to be a
better function than another viable function F2
if for all arguments
i, ICSi (F1
) is not a worse conversion sequence than ICSi(F2
), and then
for some argument j, ICSj(F1
) is a better conversion sequence than ICSj(F2
), or, if not that,
the context is an initialization by user-defined conversion (see 8.5, 13.3.1.5, and 13.3.1.6) and the
standard conversion sequence from the return type of F1
to the destination type (i.e., the type of the
entity being initialized) is a better conversion sequence than the standard conversion sequence from
the return type of F2
to the destination type.
因此,因为作为引用的隐式对象参数不是 operator char*
的 const
引用,所以根据第一个要点,它是更好的匹配。
在这种情况下
void f(int *);
void f(const int *);
...
int i;
f(&i);
情况很清楚 - f(int *) 被调用,这似乎是正确的。
但是,如果我有这个(这是错误的(*)):
class aa
{
public:
operator bool() const;
operator char *();
};
void func(bool);
aa a;
func(a);
operator char *() 被调用。我不明白为什么这样的决策路径会比使用 operator bool() 更好。有什么想法吗?
(*) 如果将 const 添加到第二个运算符,代码当然会按预期工作。
a
是 aa
的非常量实例,因此非常量转换运算符比 const 运算符(需要添加常量)更好(精确)匹配,即使 return 类型也不匹配。
您的 "aa" 对象不是 const,因此 C++ 更喜欢非常量转换。
如果将 "aa" 设为常量,则将使用 const bool() 转换运算符。
因为对于使用转换运算符的用户定义转换,返回类型到目标类型(即 char*
到 bool
)的转换被认为是 在 [=29 之后=] 对象参数转换,即对象参数a
到隐式对象参数的转换。 [over.match.best]/1:
Given these definitions, a viable function
F1
is defined to be a better function than another viable functionF2
if for all arguments i, ICSi (F1
) is not a worse conversion sequence than ICSi(F2
), and then
for some argument j, ICSj(
F1
) is a better conversion sequence than ICSj(F2
), or, if not that,the context is an initialization by user-defined conversion (see 8.5, 13.3.1.5, and 13.3.1.6) and the standard conversion sequence from the return type of
F1
to the destination type (i.e., the type of the entity being initialized) is a better conversion sequence than the standard conversion sequence from the return type ofF2
to the destination type.
因此,因为作为引用的隐式对象参数不是 operator char*
的 const
引用,所以根据第一个要点,它是更好的匹配。