次の簡略化されたバージョンのコードについて考えてみます。テンプレートクラスA
、テンプレート関数、またはなどFill
の基本的な型を処理するための関数の特殊化と、以下を処理するための別の特殊化があります。int
char
A
#include <sstream>
#include <string>
#include <iostream>
template<size_t C>
class A
{
public:
A & operator=(std::string v) {
data[0] ='a';
return *this;
}
char data[C];
};
template<typename T> T Fill(std::string value, T default_value);
// Specialization for A<C>
template<size_t C>
A<C> Fill(std::string value, A<C> default_value)
{
if (value.empty())
return default_value;
A<C> result;
result = value;
return result;
}
// Specialization for int, double, char, etc
template<typename T>
T Fill(std::string value, T default_value)
{
if (value.empty())
return default_value;
T result;
std::istringstream(value) >> result;
return result;
}
void main()
{
int abc = Fill(/*Get a string somehow*/"123", 0); // OK
A<10> def;
def = std::string("111");
A<10> a;
a = Fill(/*Get a string somehow*/"abc", def); // OK
}
コンパイラーがパラメーターを適切なテンプレートの特殊化に一致させることに成功していることに驚いていますが、これは問題なく機能します。
問題はtypedef
、の使用を容易にするいくつかのsに付属していますA<x>
。簡略化したバージョンは次のとおりです。
typedef A<12> A12;
...
A<12> def12;
def12 = std::string("12");
A12 a12;
a12 = Fill(/*Get a string somehow*/"xyz", def12); // Not OK !
コンパイラーは、型A12
が実際にあることを検出せずA<12>
、関数の誤った特殊化を使用します。これは、istringstreamがoperator>>
を使用して。に解析できないためにコンパイルされませんA
。
適切なテンプレートの特殊化を使用するにはどうすればよいですか?