其他分享
首页 > 其他分享> > c – SFINAE是否适用于职能机构?

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);
}

(Live Sample)

基于重载决策规则,非模板版本应该是首选的,因为基类的类型为Serializable.但是,我希望SFINAE在模板版本中出现错误时会启动以实现重载解析(因为如果没有为类型定义>>运算符,则不应该考虑它).

即使不使用模板,为什么它仍然失败?

解决方法:

Based on overload resolution rules, the non-template version should be
preferred because the base class is of type Serializable.

不完全的. [over.match.best]:

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,
  • […]
  • F1 is not a function template specialization and F2 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