C++ 对重载的继承函数模板使用声明会导致;对重载函数的调用不明确;

C++ 对重载的继承函数模板使用声明会导致;对重载函数的调用不明确;,c++,c++03,function-templates,C++,C++03,Function Templates,我有一个基类模板C,它实现了函数C()的多个重载,其中一个是函数模板,还有一个子类D,它继承了C并重新实现了函数模板。 D::c()导致c::c()的所有重载隐藏在D中。由于我不希望D重新实现的重载被隐藏,D通过使用C::C使它们可用 如果c()的所有重载都是非模板函数,那么这种方法很好:对于D未重新实现的重载,但对于D重新实现的重载,D的用户可以使用基本实现,来自C的实现对D的用户不可用,而使用来自D的实现 但是,如果重新实现的函数是函数模板,那么同样的方法会导致MSVC中的编译器错误 "am

我有一个基类模板
C
,它实现了函数
C()
的多个重载,其中一个是函数模板,还有一个子类
D
,它继承了C并重新实现了函数模板。
D::c()
导致
c::c()
的所有重载隐藏在
D
中。由于我不希望
D
重新实现的重载被隐藏,
D
通过
使用C::C
使它们可用

如果
c()
的所有重载都是非模板函数,那么这种方法很好:对于
D
未重新实现的重载,但对于
D
重新实现的重载,D的用户可以使用基本实现,来自
C
的实现对D的用户不可用,而使用来自
D
的实现

但是,如果重新实现的函数是函数模板,那么同样的方法会导致MSVC中的编译器错误

"ambiguous call to overloaded function
could be 'void D::c<int>(FT)
or       'void C::c<int>(FT)'"
clang和G++都能很好地编译这段代码,而MSVC11、12、14和15都无法编译。 代码的简化版本,其中
C
不是模板,而是普通类,仍然无法在MSVC 11和12中编译,但在MSVC 14和15中编译良好

在通常的方法不起作用的情况下,在C++03中,有没有更好的方法来重新实现继承的重载函数模板,而不是放弃使用
使用C::C
,而是为所有重载添加重新实现,其中一些重载只是调用它们的基本实现

注:
我不能使用C++11或任何更新的标准。

我想你误解了你链接的问题。您在一致的C++实现中的用例不应该是模棱两可的。您在
D
中声明了一个成员函数模板,其签名与
C
中的签名完全相同。链接问题使用具有不同签名的两个成员函数模板。您还可以指定您使用的确切MSVC版本吗?我使用的最早版本()可以很好地接受您的代码。@StoryTeller:代码库仍然支持的最早的VC版本是VC11(Visual Studio 2012),因此这是用于开发的版本,尽管每个版本都提供了VC12(VS 2013)、VC14(VS 2015)和VC15(VS 2017)的版本。然而,为了检查这是否是一个仅存在于旧版本中的问题,我还使用VC15测试了这段代码,该版本仍然给我相同的错误。有趣的是,您提供的godbolt链接表明,当VC16(从上个月发布的VS2019开始)是VC的最新主要版本时,它将使用VC19。我选择的godbolt选项在组合框中的MSVC 2015下分组。无论如何,这是我发现的最古老的版本,我不在日常操作中使用VC++。归根结底,这不是语言问题。Clang和G++都接受它为C++03,我还特别强调在C++03模式下再次使用旧版本。()。@StoryTeller:显然我之前的评论是错的。VC11和VC12无法编译原始的复制案例,但VC14和VC15编译得很好。然而,他们未能编译一个修改后的CRTP版本的repro案例,该案例更接近我们的真实案例,其中
C
是一个类模板,
D
继承自
C
。GCC和clang成功构建了CRTP版本。
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);
}