SFINAE是否适用于职能机构? [英] Does SFINAE apply to function bodies?
问题描述
我有以下示例代码:
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 type Serializable
. 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).
为什么即使不使用模板也仍然失败?
Why is it still failing even though the template won't be used?
推荐答案
基于重载解析规则,非模板版本应为 首选,因为基类的类型为
Serializable
.
Based on overload resolution rules, the non-template version should be preferred because the base class is of type
Serializable
.
不完全是. [over.match.best]:
Not quite. [over.match.best]:
鉴于这些定义,可行的功能
F1
被定义为 如果对于所有参数,则其功能优于另一个可行的功能F2
i,ICSi(F1)的转换顺序不比ICSi(F2)差,然后
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
- 对于某些参数j,ICSj(F1)比ICSj(F2),或(如果不是) 更好的转换顺序
- […]
-
F1
不是功能模板专业化,而F2
是功能模板专业化[…]
- 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]:
That means that only if the deduced specialization of the function template necessitates a conversion that isn't better than the conversion that the normal function necessitates, your rule applies.
And the binding of d
to Serializable&
is a worse conversion than the binding of d to MyData&
(which is the type of the parameter of the specialization), [over.ics.ref]:
当引用类型的参数直接绑定(8.5.3)到 参数表达式,隐式转换序列是恒等式 转换,除非参数表达式的类型为 参数类型的派生类,在这种情况下为隐式 转换顺序是从基数转换为基数(13.3.3.1).
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).
但是,我希望SFINAE能够在出现错误时启动 实例化版本以进行过载解析时 (因为如果未为类型定义>>运算符,则不应 被考虑).
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不适用于功能模板的内容. [温度扣除]/8:
SFINAE doesn't apply for the content of a function template. [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.
因此,确实选择了推导的功能模板的专业化,并且在实例化其定义时会导致编译器错误.
Hence the deduced specialization of the function template is indeed chosen, and causes a compiler error while instantiating its definition.
这篇关于SFINAE是否适用于职能机构?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!