能否用C++20 Concept避免基类模板函数被隐藏?请确认相关语句
关于C++模板成员函数与using声明的编译器行为确认
我想用模板特化的方式查询派生类对象的组件,下面的代码能正常运行,但作为C++新手,我不确定这个编译器行为是否可靠,希望得到确认:
#include <type_traits> class B{ public: template<class T> T* get() requires std::is_same_v< T, B>{ //... [X] return this; } }; class C : virtual public B{ public: using B::get; public: template<class T> T* get() requires std::is_same_v< T, C>{ //... [Y] return this; } }; int main(){ C c; B* b1=c.get<B>(); C* c1=c.get<C>(); B* b2=c.get<B>(); }
根据cppreference文档,即便使用using B::get,仍有如下说明:
如果派生类已有一个成员(Y)与从基类引入的成员(X)具有相同的名称、参数列表和限定条件,则派生类成员会隐藏或覆盖基类成员(不会冲突)。
我梳理了这段说明,想确认以下三个语句是否全部正确:
- [X]和[Y]具有相同的名称和参数列表。
- 但[X]和[Y]的限定条件不同。
- 因此不会发生隐藏或覆盖。
如果以上均正确,我就会依赖这个特性进行开发。
回答
你的三个判断全部正确,编译器的行为是可靠的,具体分析如下:
- 名称与参数列表:[X]和[Y]的名称都是
get,且都是无参数的模板成员函数(模板参数属于模板声明的一部分,不影响函数的参数列表),所以二者的名称和参数列表完全一致。 - 限定条件(requires子句):[X]的requires条件是
std::is_same_v<T, B>,[Y]的是std::is_same_v<T, C>,显然这两个条件不同,仅在模板实参分别为B和C时各自满足。 - 隐藏/覆盖规则:根据cppreference的说明,只有当名称、参数列表、限定条件三者都相同时,派生类成员才会隐藏基类成员。由于[X]和[Y]的限定条件不同,所以不会触发隐藏或覆盖。在调用
c.get<B>()时,只有基类的[X]满足requires条件,会被选中;调用c.get<C>()时,只有派生类的[Y]满足条件,会被选中,这完全符合你的预期。
你可以放心依赖这个特性进行开发。
内容的提问来源于stack exchange,提问作者cppBeginner
相关产品推荐
相关产品推荐

