Ho una sensazione di intestino, VS2012 è sbagliato su questo, ma non ne sono certo.Il programma viene eseguito in Visual Studio 2012 ma non ideone.com
Dopo aver cercato this question, mi sono sentito come se volessi implementare qualcosa di simile.
La mia versione funziona correttamente su Visual Studio 2012, ma non si compila nemmeno su Ideone.
Qui è la mia interfaccia principale:
#include <iostream>
#include <string>
template <class In, class Out>
struct Pipe
{
typedef In in_type ;
typedef Out out_type ;
In in_val ;
Pipe (const in_type &in_val = in_type()) : in_val (in_val)
{
}
virtual auto operator()() const -> out_type
{
return out_type() ;
}
};
template <class In, class Out, class Out2>
auto operator>> (const Pipe <In, Out> &lhs, Pipe <Out, Out2> &rhs) -> Pipe <Out, Out2>&
{
rhs = lhs() ;
return rhs ;
}
template <class In, class Out>
auto operator>> (const Pipe <In, Out> &lhs, Out &rhs) -> Out&
{
rhs = lhs() ;
return rhs ;
}
Ecco alcune classi di test:
struct StringToInt : public Pipe <std::string, int>
{
StringToInt (const std::string &s = "") : Pipe <in_type, out_type> (s)
{
}
auto operator()() const -> out_type
{
return std::stoi (in_val) ;
}
};
struct IntSquare : public Pipe <int, int>
{
IntSquare (int n = 0) : Pipe <in_type, out_type> (n)
{
}
auto operator()() const -> out_type
{
return in_val * in_val ;
}
};
struct DivideBy42F : public Pipe <int, float>
{
DivideBy42F (int n = 0) : Pipe <in_type, out_type> (n)
{
}
auto operator()() const -> out_type
{
return static_cast <float> (in_val)/42.0f ;
}
};
Ed ecco il conducente:
int main()
{
float out = 0 ;
StringToInt ("42") >> IntSquare() >> DivideBy42F() >> out ;
std::cout << out << "\n" ;
return 0 ;
}
Ideone si lamenta deduzioni template e non è in grado di trovare la corretta funzione operator>>
candidato:
prog.cpp: In function ‘int main()’:
prog.cpp:75:21: error: no match for ‘operator>>’ (operand types are ‘StringToInt’ and ‘IntSquare’)
StringToInt ("42") >> IntSquare() >> DivideBy42F() >> out ;
^
prog.cpp:75:21: note: candidates are:
prog.cpp:23:6: note: Pipe<Out, Out2>& operator>>(const Pipe<In, Out>&, Pipe<Out, Out2>&) [with In = std::basic_string<char>; Out = int; Out2 = int]
auto operator>> (const Pipe <In, Out> &lhs, Pipe <Out, Out2> &rhs) -> Pipe <Out, Out2>&
^
prog.cpp:23:6: note: no known conversion for argument 2 from ‘IntSquare’ to ‘Pipe<int, int>&’
prog.cpp:30:6: note: template<class In, class Out> Out& operator>>(const Pipe<In, Out>&, Out&)
auto operator>> (const Pipe <In, Out> &lhs, Out &rhs) -> Out&
^
prog.cpp:30:6: note: template argument deduction/substitution failed:
prog.cpp:75:35: note: deduced conflicting types for parameter ‘Out’ (‘int’ and ‘IntSquare’)
StringToInt ("42") >> IntSquare() >> DivideBy42F() >> out ;
Quale compilatore è corretto? Se Ideone è corretto, c'è qualche soluzione facile a questo codice?
Correlato a (* forse duplicato? *): [Riferimento non const associato a temporaneo, bug di Visual Studio?] (Http://stackoverflow.com/q/16380966/1708801) ... in pratica gcc è corretto qui . Se costruisci con '/ Za' in Visual Studio fallirà anche, [vedi live] (http://rextester.com/GYMOJ23021). –
È sciocco votare per chiudere questa domanda a causa * Perché questo codice non funziona *. Il test potrebbe essere più piccolo ma è un caso di test completo con risultati contrastanti tra i compilatori e non è sicuramente ovvio per la maggior parte di ciò che è corretto. –