派生模板类中基类构造函数的可见性

Visibility of a base class constructor in a derived template class

本文关键字:构造函数 可见性 基类 派生      更新时间:2023-10-16

我在编译以下代码时遇到问题,它只会导致编译错误,请参阅下文。

我不明白的是:如果我的类Any本身不是一个模板类,那么一切都可以正常工作。(您可以取消对示例代码行的注释。

如果Any是模板,则BASE_T不再可见。有什么诀窍可以让它再次出现吗?

为什么我需要BASE_T?正如您所看到的,ConcatHelper模板从该模板的变量列表中的所有类型创建一个类。现实世界中的代码做了更多的工作,但对于这里的示例来说并不重要。我定义了BASE_T来减少代码,并且不能一次又一次地复制所有模板参数。

使用过的编译器:g++5.3.1和gcc6的最新快照。

#include <iostream>
class F {};  
template<typename T>
class FReader
{   
    public:
        FReader(F&){}
};  
template<typename T> class A { };
template<typename T> class B { };

template < typename FILETYPE, typename Base, typename ...Tail> class ConcatHelper;
template <typename FILETYPE, typename Base, typename Head, typename ...Tail>
class ConcatHelper< FILETYPE, Base, Head, Tail...>: public Head, public ConcatHelper< FILETYPE, Base, Tail... >
{   
    public:
        typedef ConcatHelper< FILETYPE, Base, Head, Tail...> BASES_T;
        ConcatHelper(FILETYPE &_is): ConcatHelper< FILETYPE, Base, Tail... >(_is){}
};  
template<typename FILETYPE, typename Base>
class ConcatHelper<FILETYPE, Base>: public Base
{   
    public:
    ConcatHelper(FILETYPE& _i): Base(_i){}
};  
//class OUTER_MASTER{};
template <typename OUTER_MASTER>
class Any: public ConcatHelper<F, FReader<OUTER_MASTER>, A<OUTER_MASTER>,B<OUTER_MASTER>>
{   
    public:
        Any( F& is): BASES_T ( is ) {} // did not compile
        //Any( F& is):ConcatHelper<F, FReader<OUTER_MASTER>, A<OUTER_MASTER>,B<OUTER_MASTER>>(is) {} // compiles
};  
int main()
{   
    F f;
    Any<int> gr(f);
    //Any gr(f);
}   

结果在:

error: class 'Any<OUTER_MASTER>' does not have any field named 'BASES_T'

如果我更改:

Any( F& is): BASES_T ( is ) {}

Any( F& is): std::remove_reference<decltype(*this)>::type::BASES_T ( is ) {}

但这真的是有效的c++代码吗?

要使用模板派生类中的类型名,需要限定已使用的类型名。

正如C++标准所说(14.6.2/3):

在类模板或类模板的成员的定义中,如果类模板的基类依赖于模板参数,基类作用域在非限定名称查找过程中未检查在类模板或成员的定义点,或者在类模板或成员的实例化期间。

用类名限定构造函数有效:

template <typename OUTER_MASTER>
class Any: public ConcatHelper<F, FReader<OUTER_MASTER>, A<OUTER_MASTER>,B<OUTER_MASTER>>
{   
    public:
        Any( F& is): Any::BASES_T(is) {}
};