1

我正在尝试专注Outer<P>::Inner于如下所示的类型P,并且它似乎可以工作(在 gcc 4.5.3 和 Visual Studio 2008 上),直到Inner iOuter<P>. 有没有一种方法可以在Inner i没有专门的情况下声明Outer<P>

#include <cstdlib>
#include <iostream>

template<typename T>
struct Outer
{
    Outer()
    {
        Inner();
    }

    struct Inner;   
    //Inner i;      // compilation error
};

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

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

int main()
{
    Outer<char> o2;
    Outer<bool> o1;
    return EXIT_SUCCESS;
}
4

2 回答 2

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;
};
于 2013-01-31T17:31:19.217 回答
0

制作i(共享)指针似乎有效

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

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

这就是我认为正在发生的事情。在原始代码Inner之后声明Outer,它应该。因此,它的大小在i声明时是未知的。在上面的代码片段i中是一个指针,它的大小是已知的,尽管Inner尚未定义。

在声明之前,在 Visual Studio 2008 中“工作”但在 gcc 4.5.3 中失败,因为标准禁止这样做,所以在Inner内部进行专门化。Outeri

但是,该标准允许在类范围内进行部分专业化。这使得有一个非指针成员成为可能,i尽管模板化为一个 dummy parameter 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;
};
于 2013-01-31T19:08:16.780 回答