2011-06-18 3 views
0

さらに別のテンプレートの問題です!私は、演算子のオーバーロードがある場合、オブジェクトを出力するテンプレートメソッドを取得しようとしています< <。 私はほとんどすべての作業をしており、g ++がオブジェクトの種類ごとに目的の特殊化を選択するためにenable_ifを実装しました。テンプレートの特殊化はあいまいです

ことは、それはかなりうまく動作し、非オーバーロードされたオブジェクトと、あります。しかし、オーバーロードされたものでは、私の専門分野はどちらもg ++の合理的な選択肢です。コンパイルする代わりにあいまいなオーバーロードエラーが出力されます。そのようなことが曖昧である理由を私は理解し

template<typename T> 
    static void Print(Stream& out, T& param, typename enable_if<CanPrint<T>::value>::type = 0) 
    { 
    out << param; 
    } 

    template<typename T> 
    static void Print(Stream& out, T& param) 
    { 
    out << "/!\\" << typeid(param).name() << " does not have any overload for <<.\n"; 
    } 

は、ここでは、コードです。しかし、私はそれをもっと明白にする方法を考えることはできません...コンパイラは、最初のことができない場合にのみ、2番目のオーバーロードを選択するように理解していますか?

答えて

1

曖昧性があるため、デフォルトのパラメータ値です。 Print(stream, whatever)を呼び出す

デフォルト三パラメータと第一のバージョン、または全く三番目のパラメータを有する第二のバージョンのいずれかに解決することができます。

は、デフォルト値を削除し、コンパイラが理解するだろう。それ以外の場合は、常に両方を選択できます。

+0

はい、それは実際には事です。私はそれをどのように機能させるのですか? –

1

私は、これは、テンプレートとは何の関係もありません信じています。このような方法でオーバーロードされるフリー関数は、同じあいまいなエラーになります。

チェックこの単純なコード例で、それはあなたのテンプレートの例では何をしているかのようになります。

void doSomething(int i, int j, int k); 
void doSomething(int i, int j, int k = 10); 


void doSomething(int i, int j, int k) 
{ 

} 

void doSomething(int i, int j) 
{ 

} 


int main() 
{ 
    doSomething(10,20); 
    return 0; 
} 

エラーは次のとおりです。

明らかに
prog.cpp:18: error: call of overloaded ‘doSomething(int, int)’ is ambiguous 
prog.cpp:5: note: candidates are: void doSomething(int, int, int) 
prog.cpp:10: note:     void doSomething(int, int) 

、あなたは関数をオーバーロードすることはできませんこれはデフォルトの議論の根拠にすぎません。

+0

私は確かに知っている。本当の質問は、私がSFINAEをここに適用させる方法です。 –

+0

@ The Snake:IMHO私は誰もできるとは思わない。 'enable_if' /' disable_if'で –

+0

を実行できます。 – Node

8

どちらの場合も、最初の2つの引数としてタイプTの後にストリームを受け取る関数があるため、あいまいさがあります。これはうまくいく:

#include <iostream> 
#include <boost/utility/enable_if.hpp> 
#include <typeinfo> 

template <class T> 
struct CanPrint { enum { value = 0 }; }; 

template <> 
struct CanPrint<int> { enum { value = 1 }; }; 

template<typename T> 
typename boost::enable_if<CanPrint<T>, void>::type 
    Print(std::ostream& out, T& param) 
{ 
    out << param << std::endl; 
} 

template<typename T> 
typename boost::disable_if<CanPrint<T>, void>::type 
    Print(std::ostream& out, T& param) 
{ 
    out << "/!\\" << typeid(param).name() << " does not have any overload for <<.\n"; 
} 

int main() 
{ 
    int i = 1; 
    double d = 2; 

    Print(std::cout, i); 
    Print(std::cout, d); 
} 
+0

うわー!なんで馬鹿だ、私は戻り値を使うことを考えていなかった!それはうねり、ありがとう! –

+0

My +1、Nice答え。 –

+2

@ The-Snake実際の修正では、 'disable_if'を使って過負荷セットから '間違った'過負荷を取り除いています。 –

関連する問題