2017-11-18 6 views
0

Ich erhalte den folgenden Fehler vom Compiler: error: no match for 'operator+' (operand types are 'Expected<double>' and 'Expected<double>') Erwartet ist entweder ein Typ oder eine Ausnahme.Wie werden Operationen an zwei Vorlagen desselben Typs ordnungsgemäß ausgeführt?

template<typename T> 
class Expected 
{ 
    template<typename U> 
    Expected<U> apply(std::function<U(T)> f) 
    { 
     if(!valid) return std::get<std::exception_ptr>(state); 
     try 
     { 
      return f(std::get<T>(state)); 
     } 
     catch(...) 
     { 
      return std::current_exception(); 
     } 
    } 
}; 


#define MixedMode(op)\ 
template<typename T, typename U, typename V>\ 
Expected<U> op(Expected<T> t, Expected<V> v)\ 
{\ 
    return t.apply([&](T myT){return op(v,myT);});\ 
}\ 
template<typename T, typename U, typename V>\ 
Expected<U> op(Expected<T> t, V v)\ 
{\ 
    return t.apply([&](T myT){return op(myT,v);});\ 
}\ 
\ 
template<typename T, typename U, typename V>\ 
Expected<U> op(V v, Expected<T> t)\ 
{\ 
    return t.apply([&](T myT){return op(v,myT);});\ 
}\ 


MixedMode(operator+) 

int main() 
{ 
    Expected<double> a; 
    Expected<double> b; 

    a + b; 
} 

Ich glaube an meine Header-Datei Ich habe genug getan, um sie zu überladen und sie zusammenzufügen. In der ersten erwarte ich, dass zwei Vorlagen zusammengefügt werden. In meiner Hauptdatei rufe ich einfach an:

Expected<double> a; 
Expected<double> b; 
std::cout << a + b << std::endl; 

Und dann wird der Fehler ausgelöst. Bevor ich Expected<U> op(Expected<T> t, Expected<V> v)\ Teil des Codes hinzugefügt habe, konnte ich kompilieren und ausführen, wenn ich eine Funktion namens operator T() { return value(); } hätte, die implizit die Expected<T> auf welchen Typ auch immer übergeben wurde. Allerdings erkannte ich, dass meine apply Funktion wurde nie verwendet. Nicht nur das, wenn ich den Typ von 10 überprüfe, wurde ich ein double anstelle eines Expected<double> zurückgegeben, also beseitigte ich die operator T() Funktion, und der Compiler informierte mich, dass es nicht weiß, wie man zwei Expected<T> zusammen addiert.

Wie gehe ich vor, um diesen Fehler zu beheben? Ich habe mir den ganzen Tag den Kopf dagegengeschlagen.

+1

Könntest du das bitte in ein [mcve] schlagen? Zum Beispiel funktioniert es wahrscheinlich nicht ohne das Makro, Sie brauchen nicht alle Spreu innerhalb der Klasse. Sie können es vermutlich [https://ideone.com/cNcRpF] herunterspielen und trotzdem den gleichen Fehler bekommen. Warum mit all dem zusätzlichen Lärm experimentieren? – user4581301

+0

@ user4581301 Ich kann versuchen, es in ein minimales Beispiel zu schlagen Ich würde 'Operator <<' ausschließen, dann erkannte ich, dass ich es brauchte, damit niemand es selbst schreiben musste. Kann ich nur deine benutzen? – Sailanarmo

+0

@ user4581301 Ich habe auch das Makro, weil ich alle Operatoren mit Ausnahme von '+ =, - =, =' usw. verwenden werde. Also dachte ich, ich sollte es einfach so lassen, wie es jetzt ist. – Sailanarmo

Antwort

0

Die Körper der Vorlagenfunktionen werden niemals zum Ableiten von Vorlagenparametern verwendet. U kann nicht von den Argumenten abgeleitet werden, so dass Ihre + Überladungen ignoriert werden.

#define MixedMode(op)\ 
template<typename T, typename V>\ 
auto op(Expected<T> t, Expected<V> v)\ 
{\ 
    return t.apply([&](T myT){return op(v,myT);});\ 
}\ 
template<typename T, typename V>\ 
auto op(Expected<T> t, V v)\ 
{\ 
    return t.apply([&](T myT){return op(myT,v);});\ 
}\ 
template<typename T, typename V>\ 
auto op(V v, Expected<T> t)\ 
{\ 
    return t.apply([&](T myT){return op(v,myT);});\ 
} 

Dies wird nicht kompilieren, aber das ist, weil Sie falsch apply schrieb. Eine std::function ist kein Lambda, und ein Lambda ist kein std::function. Wenn Sie den Typ einer std::function 999/1000 Male herleiten, die Sie vermasseln, ist, weil std::function über Art Löschung ist und Abzug über Typenabzug ist, und das sind entgegengesetzte Konzepte.

Noch wichtiger, Sie komponieren sie rückwärts, und sie komponieren nicht so.

template<class F> 
Expected<std::invoke_result_t<F&,T&>> apply(F f){ 

oder etwas ähnliches.

+0

Tut mir leid, es dauert mich manchmal, um meinen Kopf um Ihre Antwort zu wickeln. Aber ich bin mir immer noch nicht sicher, wie die Bewerbung falsch geschrieben ist. Wenn das Ergebnis keine Ausnahme ist, versuchen Sie, die Operation durchzuführen, die ich annimmt, ist "Erwartet + Erwartete " und gibt das Ergebnis davon zurück. Fangen Sie die Ausnahme, wenn es welche gibt. Ich habe auch 'std :: invoke_result_t' noch nie gesehen Möchten Sie erklären, wie das funktioniert? Und schließlich, wenn die Anwendung korrekt ausgeführt wird, wird der Rest der Compilerfehler verschwinden? – Sailanarmo

+0

Ich gab korrigierten Code. Was ist daran unklar? Ich habe einen Antrag gestellt. Ich habe Fehler behoben, die ich entdecken konnte. Ihre Frage fehlt ein [mcve], also weiß ich nicht, welche anderen Fehler es gibt, noch habe ich meinen Code auf einem Online-Compiler getestet, damit ich Tippfehler haben konnte. Haben Sie versucht, 'std :: invoke_result 'zu googeln und sagen Sie [diese Seite] (http://en.cppreference.com/w/cpp/types/result_of)? Wenn Sie nach dem Lesen neue Fragen haben, fragen Sie sie über die Schaltfläche "Frage stellen" oder suchen Sie nach einem guten Plan. Kommentare sind zu kurz. – Yakk

Verwandte Themen