我有一个实现函数C
的多个重载的基类模板c()
,其中一个是函数模板,还有一个子类D
,它从C继承并重新-实现功能模板。
D::c()
导致C::c()
的所有重载都隐藏在D
中。因为我希望不要隐藏D
没有重新实现的重载,所以D
通过using C<D>::c
使它们可用;
如果c()
的所有重载都是非模板函数,这将很好地工作:D的用户可以使用基本实现来实现D
没有重新实现的重载,而对于{{1 }}重新实现,D的用户无法使用D
中的实现,而使用C
中的实现。
但是,如果重新实现的功能是功能模板,则相同的方法会导致MSVC中的编译器错误。
D
显然,对于模板,"ambiguous call to overloaded function
could be 'void D::c<int>(FT)
or 'void C::c<int>(FT)'"
实现对C
用户可用,并且与D
中的重新实现冲突。
D
clang和G ++都可以很好地编译此代码,而MSVC 11、12、14和15都无法编译它。
其中template<typename T>
class C
{
public:
void c(void){}
template<typename FT> void c(FT param){}
};
class D : public C<D>
{
public:
using C<D>::c;
template<typename FT> void c(FT param){}
};
int main()
{
D d;
d.c<int>(1);
}
不是模板而是普通类的简化代码版本在MSVC 11和12中仍然无法编译,但在MSVC 14和15中可以正常编译。
在通常的方法不起作用的情况下,在C ++ 03中,有什么比放弃使用C
而不是为所有重载添加重新实现更好的方法来重新实现继承的重载函数模板了?有些只不过是调用其基本实现而已?
注意: 我不能使用C ++ 11或任何更新的标准。