2

次の簡略化されたバージョンのコードについて考えてみます。テンプレートクラスA、テンプレート関数、またはなどFillの基本的な型を処理するための関数の特殊化と、以下を処理するための別の特殊化があります。intcharA

#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

適切なテンプレートの特殊化を使用するにはどうすればよいですか?

4

3 に答える 3

4

テンプレートの特殊化は、戻り値を割り当てる場所からは推測されません。正しいバージョンを明示的にインスタンス化する必要があります。

a12 = Fill<A<12> >("xyz", def);

(または必要なものは何でも...)

于 2011-05-19T15:40:55.823 に答える
1
typedef A<12> A12;
...
A12 a12;
a12 = Fill(/*Get a string somehow*/"xyz", def);       // Not OK !

この例では、のタイプを示していませんdef。前の例と同じであると仮定すると、つまりA<10>、これは確かに失敗します。

テンプレートでは、2番目のパラメーターのタイプが戻りタイプと一致する必要があります。これを試して:

typedef A<12> A12;
...
A12 a12;
A12 def12;
a12 = Fill(/*Get a string somehow*/"xyz", def12);       // OK !
于 2011-05-19T15:51:40.097 に答える
0

コンパイラーは、タイプA12が実際にはA <12>であることを検出せず、関数の誤った特殊化を使用します

実際、あなたはA<12> def;あなたの例を渡しているので(間違い?)、正しいオーバーロード(質問に関する私のコメントを参照)を選択する必要があります。結果をに割り当てるという事実は、A12 a;過負荷の解決に影響を与えるべきではありません。

反対のことを意味する場合(パスA12して何にでも割り当てる)、これはコンパイラの欠陥である可能性があります。これはここで正しく機能します。

于 2011-05-19T17:54:00.563 に答える