1

Outer<P>::Inner以下に示すように型に特化しようとしていますが、でメンバー変数が宣言さPれるまで、(gcc4.5.3およびVisualStudio 2008で)機能しているように見えます。専門化せずに宣言する方法はありますか?Inner iOuter<P>Inner iOuter<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はまだ定義されていませんが、わかっています。

を宣言する前にInner内部で特殊化することは、Visual Studio 2008 では「機能」しますが、gcc 4.5.3 では失敗します。これは、標準で禁止されているためです。Outeri

ただし、標準では、クラス スコープでの部分的な特殊化が許可されています。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;
};
于 2013-01-31T19:08:16.780 に答える