6

私は通常、クラスとテンプレートを宣言し、その後にそれらのメソッドを定義します(もちろん、同じヘッダーファイルで)。私はそのように読むほうが簡単だと思います。さて、クラス外の定義で使用する作業型シグネチャを理解できない場合があります。これが私がしていることの簡単な例で、問題を説明しています:

template <class T>
struct Foo
  {
    Foo(T a, T b);

    template 
      < class Iterator
      , enable_if< is_iterator<Iterator> >
      >
    Foo
      ( Iterator first
      , Iterator last
      );
  };

template <class T>
Foo<T>::Foo(T a, T b)
{ ... }

template <class T>
template
  < class U
  , WHAT_GOES_HERE?
  >
Foo<T>::Foo(U f, U l)
{ ... }

一致する署名を取得するためにスロット内でいくつかのことをWHAT_GOES_HERE試みましたが、失敗し続けます。タイプTの2つのオブジェクトを渡す場合と、イテレータのペアを渡す場合を区別するために、enable_ifが必要です。テンプレート化されたコンストラクターがメインテンプレート内で定義されている場合、コードは正常に機能します。これは、コードが現在行っている方法ですが、定義を宣言の外に移動したいと思います。

編集: enable_if <...>はそのタイプにデフォルト値を割り当てるため、定義でenable_if <...>を再利用することはできません。これは、そうでない定義では実行できません。また、宣言。

4

4 に答える 4

3

私はそのようにはしません。これが私が行う変更です:

template <class T>
struct Foo
  {
    Foo(T a, T b);

    template 
      < class Iterator
      >
    Foo
      ( Iterator first
      , Iterator last
      , typename enable_if<is_iterator<Iterator> >::type* = 0
      );
  };

template <class T>
Foo<T>::Foo(T a, T b)
{ ... }

template <class T>
template
  < class U
  >
Foo<T>::Foo(U f, U l, typename enable_if< is_iterator<U> >::type*)
{ ... }

これは、のドキュメントから直接引用したものですenable_if

于 2011-02-27T20:30:38.063 に答える
2

これはあなたが達成しようとしていることですか?[is_iteratorタイプ特性がないので、C++0xタイプ特性とユーティリティライブラリを使用して例を作り直しました。TR1およびBoostライブラリでも同じように機能するはずです。]

#include <utility>
#include <type_traits>

template <typename T>
struct S
{
    // Constructor (1)
    S(T, T); 

    // Constructor (2)
    template <typename U>
    S(U, U, typename std::enable_if<std::is_integral<U>::value>::type* = 0);
};

template <typename T>
S<T>::S(T, T)
{ }

template <typename T>
template <typename U>
S<T>::S(U, U, typename std::enable_if<std::is_integral<U>::value>::type*)
{ }

int main()
{
    S<double> a(1.0, 2.0); // uses (1)
    S<double> b(1, 2);     // uses (2)
}
于 2011-02-27T20:30:04.807 に答える
1

あなたができる最も簡単なことは:

template<class Iterator>
Foo
  ( Iterator first
  , typename enable_if<is_iterator<Iterator>, Iterator>::type last
  );
于 2011-02-27T20:34:44.193 に答える
1
template <class T>
struct Foo
  {
    Foo(T a, T b);

    template <class Iterator
      ,       class = typename std::enable_if
                       <is_iterator<Iterator>::value>
                       ::type
      >
    Foo
      ( Iterator first
      , Iterator last
      );
  };

template <class T>
Foo<T>::Foo(T a, T b)
{  }

template <class T>
template
  < class U
  , class >
Foo<T>::Foo(U f, U l)
{  }
于 2011-02-27T20:36:43.663 に答える