この明示的な専門化を行うにはどうすればよいですか?
-
28-09-2019 - |
質問
次の設計は可能ですか?:
template <typename T>
class Test{
public:
template <typename Z>
void doSomething();
//rest of things
private:
T obj;
//some things
};
それが可能であれば、私は何かのためにいくつかの明示的な専門化を行うので、最後に以下のようないくつかのバージョンがあります。
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':テンプレートの引数が少なすぎます。
解決
明示的に専門化するために doSomething
また、明示的に専門化する必要があります Test
.
14.7.3/18から:
名前空間スコープに表示されるクラステンプレートまたはメンバーテンプレートのメンバーの明示的な専門宣言では、メンバーテンプレートとその囲みのクラステンプレートの一部は専門化されていないままである場合があります。 宣言がクラスメンバーのテンプレートを明示的に専門化してはならないことを除いて.
他のヒント
囲まれたクラステンプレートも明示的に専門化されていない限り、メンバーテンプレートを明示的に専門化することはできません。
したがって、このようなものだけが機能します:
template<> template<>
void Test<int>::doSomething<int>()
{
}
いつでも関数をインラインにすることができます
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;
};
これはうるさいと思います。私はあなたがそれをすることができないと思います、読んでください これ.
これが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>();
}
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では面白いことは、インライン定義を専門とするときにコンパイルするのに問題はありませんが、非インライン定義を備えた専門分野では、複数のバージョンがあり、正常にコンパイルされません。