6

以下の設計は可能ですか?:

template <typename T>
class Test{
 public:
  template <typename Z>
  void doSomething();
  //rest of things
 private:
  T obj;
  //some things
};

可能であれば、doSomethingに明示的な特殊化を行って、最終的に次のようなバージョンを作成します。

void doSomething<int>(){
 //do something
}
void doSomething<double>(){
 //do something
}
...etc

これは不可能のようですが、仕事をするための構文が見つからないので、すべてのテンプレート引数をテンプレートクラス自体に渡すように、次のように設計する必要があると思いました。

template <typename T,typename Z>
class Test{
 public:
  void doSomething();
  //rest of things
 private:
  T obj;
  //some things
};

次に、コンパイルすらしなかった部分的な特殊化を試しました。

template <typename T>
void Test<T,int>::doSomething(){
 //do something
}
template <typename T>
void Test<T,double>::doSomething(){
 //do something
}
...etc

明示的な特殊化で次のエラーが発生しました。
エラー#1:クラステンプレート名に続くテンプレート引数リストは、テンプレートパラメータリストで使用されている順序でパラメータをリストする必要があります。
エラー#2:'Container1':テンプレート引数が少なすぎます。

4

6 に答える 6

6

明示的に専門化するには、明示的に専門化doSomethingする必要もありますTest

14.7.3 / 18から:

クラステンプレートのメンバーまたは名前空間スコープに表示されるメンバーテンプレートの明示的な特殊化宣言では、メンバーテンプレートとそれを囲むクラステンプレートの一部が特殊化されないままになる場合があります。ただし、宣言がクラスメンバーテンプレートを明示的に特殊化しない場合を除きます。同封のクラステンプレートも明示的に特殊化されていません

于 2010-11-25T08:08:37.177 に答える
2

囲んでいるクラステンプレートも明示的に特殊化されていない限り、メンバーテンプレートを明示的に特殊化することはできません。

したがって、このようなものだけが機能します。

template<> template<>
void Test<int>::doSomething<int>()
{
}
于 2010-11-25T08:17:18.460 に答える
1

関数はいつでもインラインにすることができます

template <class T>
class Test
{
public:
 template <class Z>
 void doSomething() { cout << "default" << endl; }

 template<>
 void doSomething<int>() { cout << "int" << endl;}
 template<>
 void doSomething<double>() { cout << "double" << endl; }
private:
 T obj;
};
于 2010-11-25T08:28:35.480 に答える
0

これはうるさいと思います。私はあなたがそれをすることができないと思います、これを読んでください。

于 2010-11-25T08:22:52.593 に答える
0

これがg++のバグであるかどうかはわかりませんが、これはコンパイルされ、私が期待するものを生成します。

#include<typeinfo>
#include<iostream>

template<typename T>
class Test
{
public:
    template<typename Z>
    void doSomething();

private:
    T obj;
};

template<typename T>
template<typename Z>
void Test<T>::doSomething()
{
    Z val;
    std::cout << __func__ << ": type " << typeid(val).name() << std::endl;
}

int main(int argc, char *argv[])
{
    Test<double> a;
    a.doSomething<int>();
    a.doSomething<double>();
}
于 2010-11-25T14:33:12.127 に答える
-2

icecrimeは一時的な回答を投稿しましたが、おそらくVisual C++2008によるバグが原因でコンパイルされます。

template <typename T>
class Test{
 public:
  template <typename Z>
  void doSomething();
  //rest of things
 private:
  T obj;
  //some things
};
template <>
template <typename T>
void Test<T>::doSomething<int>(){
 //do something
}

しかし、彼の現在の答えを確認してください。少なくともVC++2008で面白いのは、インライン定義で特殊化する場合はコンパイルに問題はありませんが、インライン定義ではない特殊化では、複数のバージョンがあると正常にコンパイルされないことです。

于 2010-11-25T08:23:04.880 に答える