【问题标题】:typedefs from the template parameter of template class are invisible来自模板类的模板参数的 typedef 是不可见的
【发布时间】:2012-11-09 14:44:47
【问题描述】:

给定一个基类,它包含公共静态方法以及所有派生类的一般逻辑(例如创建它们)。子类模板的参数化类型被传递给基类模板(连同子类的类型,以便在基类的静态方法中访问其自定义静态方法)。这些类型的组合是类型定义的新“类型”(这是在基类中完成的,以避免重复某些代码)。然后他们在派生类的公共部分重新定义(类似)。我会在包含帮助器的类中使用这些类型定义,如下所示:

#include <iostream>
#include <vector>

#include <cmath>
#include <cstdlib>

template< class DERIVED >
class HELPERS;

template< class V, class DERIVED >
struct BASE
{

    typedef typename V::value_type F;

    static
    F some_common_operation()
    {
        return helpers.approximate_x(DERIVED::value()); // some common logic (HELPERS::approximate_x() here) depending on the value of DERIVED::value()
    }

    static
    DERIVED create_biased(F const & x)
    {
        return DERIVED(F(0.5) * (x + some_common_operation()));
    }

protected :

    BASE(F const & x_)
        : x(x_)
    { ; }

    F x;

private :

    static
    HELPERS< DERIVED > const helpers;

};

template< class V, class DERIVED >
HELPERS< DERIVED > const BASE< V, DERIVED >::helpers;

template< class V >
class DERIVED
    : public BASE< V, DERIVED< V > >
{

    typedef BASE< V, DERIVED< V > > B;
    friend B;

public :

    typedef typename B::F F;

    DERIVED(F const & x_)
        : B(x_)
    { ; }

    F shape(F const & y) const
    {
        return y * x;
    }

private :

    static constexpr
    F value()
    {
        return F(2.0L); // custom data
    }

    using B::x;

};

// template< class > class DERIVED1;...

template< class D >
struct HELPERS // set of helpers, that operates on classes derived from BASE
{

    typedef typename D::F F; // error: no type named <F> in <class DERIVED<std::vector<double> >>

    F approximate_x(F const & x) const
    {
        using std::sqrt;
        return sqrt(x);
    }

};

int main()
{
    DERIVED< std::vector< double > > d(2.0L);
    return EXIT_SUCCESS;
}

我正在尝试获取帮助程序类中的定义,但出现错误 (g++ -std=gnu++11 a.cpp)。

a.cpp: In instantiation of «struct HELPERS<DERIVED<std::vector<double> > >»: a.cpp:44:26: required from «struct BASE<std::vector<double>, DERIVED<std::vector<double> > >» a.cpp:47:7: required from «class DERIVED<std::vector<double> >» a.cpp:97:39: required from here a.cpp:85:27: error: no type named «F» in «class DERIVED<std::vector<double> >»

怎么了? Typedef 及其所有“祖先”都可以在类链中访问(放置在公共部分中)。

【问题讨论】:

    标签: c++ templates inheritance typedef


    【解决方案1】:

    这是一个鸡蛋问题。

    这是因为在您定义 BASE 时,DERIVED 尚未完全定义(因为编译器需要先解析基类)。因此,您无法访问 DERIVED 中的任何类型定义 HELPER。为了确保您可以检查以下是否正常工作:

    template< class V, class DERIVED >
    struct BASE
    {
        typedef typename V::value_type F;
        typedef typename DERIVED::F G; // <-- error here
        ...
    }
    

    您可以尝试将HELPER 的使用转移到DERIVED,或者使用V 作为HELPER 的参数。

    【讨论】:

    • 最后我使用V 作为HELPER 的参数,但是很难看,因为这会增加模板参数的数量。我没有将 HELPER 作为参数传递,因为对于所有关注的派生类都必须这样做。每次。这会炸毁代码。
    • Base 已经将V 作为参数。不知道为什么还需要一个参数,你可以在HELPER 中替换它,不是吗?
    猜你喜欢
    • 2012-11-04
    • 1970-01-01
    • 1970-01-01
    • 2010-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-10
    相关资源
    最近更新 更多