专门研究内部类的实现

时间:2013-01-31 17:25:09

标签: c++ templates

我正在尝试在类型Outer<P>::Inner上专门化P,如下所示,它似乎可以工作(在gcc 4.5.3和Visual Studio 2008上),直到成员变量{{1} }在Inner i中声明。是否可以在没有专门化Outer<P>的情况下声明Inner i

Outer<P>

2 个答案:

答案 0 :(得分:2)

必须在命名空间级别完成专业化。因此,最简单的方法是在命名空间级别声明Inner

template <typename T>
struct Outer_Inner
{
  Outer_Inner()
  {
    std::cout << "Generic version ..." << std::endl;
  }
};

template <>
struct Outer_Inner<bool>
{
  Outer_Inner()
  {
    std::cout << "Specialization ..." << std::endl;
  }
};


template<typename T>
struct Outer
{
  Outer() : i()
  {
  }

  Outer_Inner<T> i;      // no error anymore
};

在C ++ 11中,有一种解决方法可以在类中定义所有内容,但我不推荐它。

template<typename T>
struct Outer
{
  Outer() : i()
  {
  }

  struct generic_inner
  {
    generic_inner()
    {
      std::cout << "Generic version ..." << std::endl;
    }
  };

  struct special_inner
  {
    special_inner()
    {
      std::cout << "Specialization ..." << std::endl;
    }
  };

  typename std::conditional<std::is_same<T, bool>::value,
                            special_inner, generic_inner>::type i;
};

答案 1 :(得分:0)

使i a(共享)指针似乎可以正常工作

template<typename T>
struct Outer
{
    Outer() : i( new Inner() )
    {
    }

    struct Inner;   
    boost::shared_ptr<Inner> i;
};

这就是我的想法。原始代码InnerOuter之后声明,应该如此。因此,i的大小在声明时是未知的。在上面的代码段中,i是一个指针,即使尚未定义Inner,其大小也已知。

在声明Inner之前,在Outer内专门i,“在Visual Studio 2008中工作”但在gcc 4.5.3中失败,因为标准禁止它。 / p>

然而,该标准允许在类范围内进行部分特化。这使得有一个非指针成员i虽然可以在虚拟参数T2=T1上进行模板化,如下所示,尽管我认为我将使用(智能)指针版本。

template<typename T1>
struct Outer
{
    template<typename T2,bool>
    struct Inner; 

    template<typename T2>
    struct Inner<T2,true>
    {
        Inner()
        {
            std::cout << "# Specialization ..." << std::endl;
        }
    };

    template<typename T2>
    struct Inner<T2,false>
    {
        Inner()
        {
            std::cout << "# Generic version ..." << std::endl;
        }
    };  

    Outer()
    {
    }

    Inner<T1,boost::is_same<T1, bool>::value> i;
};