C++ SFINAE是否适用于职能机构?
我有以下示例代码:C++ SFINAE是否适用于职能机构?,c++,templates,language-lawyer,overload-resolution,upcasting,C++,Templates,Language Lawyer,Overload Resolution,Upcasting,我有以下示例代码: 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
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);
}
类可序列化{};
类MyData:public Serializable{};
void GetData(可序列化&){}
模板
无效GetData(T&data)
{
std::istringstreams{“test”};
s>>数据;
}
int main()
{
MyData d;
获取数据(d);
}
()
基于重载解析规则,应首选非模板版本,因为基类的类型为可序列化
。但是,当模板版本为重载解析而实例化时出现错误时,我希望SFINAE能够启动(因为如果没有为类型定义>>运算符,则不应考虑它)
为什么即使不使用模板,它仍然失败
根据重载解析规则,非模板版本应为
首选,因为基类的类型为可序列化
不完全是。[结束,比赛,最佳]:
根据这些定义,可行函数F1
被定义为
比另一个可行函数更好的函数F2
if用于所有参数
i、 ICSi(F1)不是比ICSi(F2)更差的转换序列,然后
- 对于某些参数j,ICSj(F1)是比ICSj(F2)更好的转换序列,或者,如果不是那样,
- [……]
不是函数模板专用化,F1
是函数模板专用化[…]F2
d
绑定到Serializable&
比将d绑定到MyData&
(这是专门化的参数类型)的转换更糟糕,[over.ics.ref]:
当引用类型的参数直接(8.5.3)绑定到
参数表达式,隐式转换序列是标识
转换,除非参数表达式的类型为
参数类型的派生类,在这种情况下,隐式
转换顺序是从派生到基本的转换(13.3.3.1)。
然而,我希望SFINAE在测试中出现错误时能够发挥作用
为重载解析实例化模板时的模板版本
(因为如果未为类型定义>>运算符,则不应定义该运算符。)
(将予以考虑)
SFINAE不适用于函数模板的内容。[临时扣除]/8:
在的直接上下文中,只有无效的类型和表达式
函数类型及其模板参数类型可导致
扣除失败
因此,确实选择了推导出的函数模板专门化,并在实例化其定义时导致编译器错误。
只有在完全匹配的情况下,才应首选非模板版本。看看如果你使用MyData
而不是Serializable
会发生什么。这里“专门化”一词的标准用法实际上是模板的“实例化”,对吗?因为在我看来,专门化是指当函数显式地为类型实现时。在我的例子中,我没有明确地专门化基本函数模板。@void.pointer似乎您混淆了术语。专门化是使用推导的模板参数实例化的函数。你说的是明确的专业化。