c – SFINAE是否适用于职能机构?
作者:互联网
我有以下示例代码:
class Serializable {};
class MyData : public Serializable {};
void GetData( Serializable& ) {}
template<typename T>
void GetData( T& data )
{
std::istringstream s{"test"};
s >> data;
}
int main()
{
MyData d;
GetData(d);
}
基于重载决策规则,非模板版本应该是首选的,因为基类的类型为Serializable.但是,我希望SFINAE在模板版本中出现错误时会启动以实现重载解析(因为如果没有为类型定义>>运算符,则不应该考虑它).
即使不使用模板,为什么它仍然失败?
解决方法:
Based on overload resolution rules, the non-template version should be
preferred because the base class is of typeSerializable
.
不完全的. [over.match.best]:
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,
- […]
F1
is not a function template specialization andF2
is a function template specialization […]
这意味着,只有在推断出功能模板的特化时,才需要转换不比正常功能所需的转换更好,您的规则才适用.
并且d与Serializable&的绑定比d与MyData&的结合更糟糕的转换. (这是专业化参数的类型),[over.ics.ref]:
When a parameter of reference type binds directly (8.5.3) to an
argument expression, the implicit conversion sequence is the identity
conversion, unless the argument expression has a type that is a
derived class of the parameter type, in which case the implicit
conversion sequence is a derived-to-base Conversion (13.3.3.1).
However, I expect SFINAE to kick in when there are errors in the
template version when it is instantiated for overload resolution
(because if the >> operator is not defined for a type, it should not
be considered).
SFINAE不适用于功能模板的内容. [temp.deduct] / 8:
Only invalid types and expressions in the immediate context of the
function type and its template parameter types can result in a
deduction failure.
因此,确实选择了函数模板的推导特化,并在实例化其定义时导致编译器错误.
标签:upcasting,c,language-lawyer,templates,overload-resolution 来源: https://codeday.me/bug/20190830/1767030.html