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

时间:2016-04-15 12:36:12

标签: c++ templates

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

我不明白的是: 如果我的类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 ++代码吗?

1 个答案:

答案 0 :(得分:4)

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

正如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) {}
};