2011-01-18 19 views
4

私のコンパイラは私のテンプレートメソッドを実装する方法に満足していません。これらの実装では、トンのが「未定義のタイプT」のようなエラーメッセージを表示します。これは私の第一の方法であるテンプレート以外のクラスのテンプレートメソッドを定義するにはどうすればよいですか?

、それはクラスのブロックの外に実装されています。

class VectorConvertor 
{ 
    public: 
     // ... 
     template <class T> 
     static void ReverseVectorElements(std::vector<T> & Vector); 
     // ... 
}; 

template <class T> 
void VectorConvertor::ReverseVectorElements(std::vector<T> & Vector) 
{ 
    std::vector<T>::size_type size = Vector.size(); 
    T swap; 
    for (std::vector<T>::size_type i=0; i<size/2; i++) 
    { 
     swap = Vector.at(i); 
     Vector.at(i) = Vector.at(size-1-i); 
     Vector.at(size-1-i) = swap; 
    } 
} 

もう一つはこれです。今回はメソッドがクラス内で実装されています:

class ElementaryMath 
{ 
    public: 
     // ... 
     template <class T> static char sign(T num) 
     { 
      return (num >= static_cast<T>(0)) ? static_cast<char>(+1) : static_cast<char>(-1); 
     } 
     // ... 
} 

私のコードに何か問題がありますか、それともコンパイラ自体に問題がありますか?

IDE &コンパイラ:Visual Studioの2010

答えて

5

:助けるが、明らかにそのベータ...ここ

+0

@hkBattousai:winapiの最大と最小のマクロは一定の頭痛の原因です。 winapiがそれらを作成するのを防ぐために、(プロジェクト設定で行うのが最善の)特別な設定マクロがあります。たとえば、http://connect.microsoft.com/VisualStudio/feedback/details/101300/std-numeric-limits-min-std-numeric-limits-max-and-min-max-macrosを参照してください。あなたのコメントを削除する前にもっと意味を成していましたが、私はそれがまだ当てはまると思うので、ここに残しています。 –

+0

ああ、あなたは本当にその場に出ました。関数 "sign()"はありませんでしたが、別のもの(最初のコンパイラエラー)、 "max()"はあなたが言ったのと同じように定義されています。私は以下のように定義していないので、コンパイラエラーはありません。 >> '#ifdef max --- #undef max --- #end' – hkBattousai

4

あなたは、いくつかのtypename sおよびセミコロンを逃しているが、それ以外、コードはOKらしいです。 IMHOそれはまだ動作しない場合、バグを提出する時間です。

ところで、スワップコードはstd::swapで行う方がよいでしょう。

+1

{std :: swap; swap(a、b);}を使用してstd :: swapを使用することに加えて、ループ全体をstd :: swap_ranges(Vector.begin() – Grizzly

+0

iter_swapでさらに良くなっています – CashCow

+3

@Grizzlyもし彼がしたいことがあれば、彼はちょうど逆にすることができます:: reverse – CashCow

1

あなたのコードはコンパイラのバグを見ているかもしれないので、VS2005(ElementaryMathの定義の最後にセミコロンがありません。

VS2010 SP1は、ベータ版hereで利用できます。あなたのコードは、私にはOKに見える

template <class T> 
void VectorConvertor::ReverseVectorElements(std::vector<T> & Vector) 
{ 
    typename std::vector<T>::size_type size = Vector.size(); 
    T swap; 
    for (typename std::vector<T>::size_type i=0; i<size/2; i++) 
    { 
     swap = Vector.at(i); 
     Vector.at(i) = Vector.at(size-1-i); 
     Vector.at(size-1-i) = swap; 
    } 
} 
+0

「typename」という答えは、テンプレートパラメータリストではなく、依存型に関するものです。 –

+0

完全に間違った答えですが、私は今日downvotingでやっています。 – CashCow

+0

@FredNurkありがとう、私はそれを認識しませんでした。私はtypenameについて誤解を招く部分を削除しました。 –

1

型名かもしれません。しかし、私の心の中には1つのことがあります。前に関数 "sign"が定義されているかどうか確認してください。その上にマウスを置くだけです。 Cランタイムライブラリは関数のいくつかを "#define"キーワードを使って実装しているので、後で同じ名前の関数を定義することはできません。

1
class VectorConvertor 
{ 
    public: 
    // ... 
    template <typename T> 
    static void ReverseVectorElements(std::vector<T> & Vector); 
}; 

template <typename T> 
void VectorConvertor::ReverseVectorElements(std::vector<T> & Vector) 
{ 
    std::vector<T>::size_type size = Vector.size(); 
    T swap; 
    for (std::vector<T>::size_type i=0; i<size/2; i++) 
    { 
     swap = Vector.at(i); 
     Vector.at(i) = Vector.at(size-1-i); 
     Vector.at(size-1-i) = swap; 
    } 
} 

int main() 
{ 
    std::vector <int> i(10,0); 

    VectorConvertor obj; // Since your class isn't a template, template parameter 
          // isn't required for a class template instantiation. 
          // However, if your class was a template class, template- 
          // parameter must have been required for a class template 
          // instantiation. 

    obj.ReverseVectorElements(i); // Equal to obj.ReverseVectorElements<int>(i); 
            // Based on type of i, compiler can instantiate a 
            // template function by default. 
    getchar(); 
    return 0; 
} 

+0

[コンパイルしようとしましたか](http://codepad.org/QQOi7sCT)これは?(msvcのいくつかのバージョンでは、依存名が間違っていることに注意してください。) –

+0

Visual C++ 2010で試しました。うまくいきました。 – Mahesh

+0

まあ、間違っています。 –

関連する問題