模板实例化不"do inheritance"
Template instantiation does not "do inheritance"
标题引用自SO答案。讨论了使用SFINAE检测具有给定签名的成员函数的存在性,并指出了该方法在处理继承成员函数时在接受答案中的一个失败之处。特别是,给出的解释如下
如果你还不知道这个问题,那么看看标题中
std::shared_ptr<T>
的定义就会明白。在该实现中,std::shared_ptr<T>
是从继承operator*() const
的基类派生的。因此,构成为U = std::shared_ptr<T>
"查找"运算符的模板实例化SFINAE<U, &U::operator*>
不会发生,因为std::shared_ptr<T>
本身没有operator*()
,模板实例化也没有"继承"。这个障碍并不影响众所周知的SFINAE方法,该方法使用"the sizeof()Trick",仅用于检测T是否具有某个成员函数mf(参见例如这个答案和注释)。
使用答案中的术语,使用T::mf
作为模板参数实例化类型与让编译器通过模板函数参数推导来确定类型之间有什么区别?"模板实例化不做继承"是什么意思?最后,为什么这不影响简单地检查成员的存在,就像这里一样?
最小化示例:
struct A {
void a() const;
};
struct B : A {};
template<typename U, void (U::*)() const> struct SFINAE {};
template<typename U> void Test(SFINAE<U, &U::a>*) { }
int main(void)
{
Test<B>(0); // doesn't compile
return 0;
}
演示。
问题是,当B::a
从A
继承时,&B::a
的类型实际上是"指向A
成员的指针",并且,虽然通常指向基成员的指针可以隐式转换为指向派生成员的指针,但根据§14.3.2[temp.arg.notype]/p5:,这种转换不适用于非类型模板参数
对用作非类型模板参数。如果非类型模板参数不能转换为相应模板参数的类型则该程序是格式错误的。
- […]
- 对于指向成员函数的指针类型的非类型模板参数,如果模板参数的类型为
std::nullptr_t
应用空成员指针转换(4.11);否则,否转换适用。如果模板参数表示重载成员函数,则选择匹配的成员函数来自集合(13.4)
相关文章:
- 为什么"do while"循环不断退出,即使条件计算结果为 false?
- 如果条件为TRUE(最佳方式?),则在do while循环中后置增量
- 即使没有满足他们的条件,我也无法通过一些 do-while 循环
- 如何使用 do while 循环确定最高值和最低值
- do while 循环中的 if 语句以 yes 或 no 结尾
- 以某种方式告诉编译器"Do not process line of code"
- 在 C 或 C++ 中,循环可以同时具有 "do" 和"while"部分吗?
- 使用 while 或 do while 退出循环
- 带有开关语句的 do-while 循环 -- 无穷循环错误
- 为什么当我输入一个被接受的数字时,我的 do-while 循环没有中断?
- 为什么我的 Do-while 循环无法在C++中运行菜单
- 如果语句不会在 do - while 循环中运行
- 开放CV垫"Sizes of input arguments do not match"的问题
- 为什么当我对数组使用增量操作时,do for 循环不起作用
- 如何在c++中读取do-while循环中的空白
- 尝试应用肖恩父母谈话"inheritance is the base class of evil"中的模式
- 什么是'do while loop'的真实应用?
- 将嵌套的 for 循环更改为 do-while 循环
- 如何修复不会在退出选择时终止的 do-while 循环
- 模板实例化不"do inheritance"