It seems like this should be legal:
decltype(declval<istream>().operator>>(declval<istream>(), declval<int>())) test;
But when I try to compile I get:
error C2661:
std::basic_istream<char,std::char_traits<char>>::operator >>
: no overloaded function takes 2 arguments
Am I doing something wrong? Why doesn't this evaluate to an istream
?
EDIT:
It has been pointed out that because istream& istream::operator>>(int&)
is a method, the first value is passed automatically.
However: decltype(declval<istream>().operator>>(declval<int>())) test;
errors with:
error C2664:
std::basic_istream<char,std::char_traits<char>> &std::basic_istream<char,std::char_traits<char>>::operator >>(std::basic_streambuf<char,std::char_traits<char>> *)
: cannot convert argument 1 fromstd::ios_base::iostate
tostd::basic_istream<char,std::char_traits<char>> &(__cdecl *)(std::basic_istream<char,std::char_traits<char>> &)
And decltype(istream::operator >> (declval<istream>(), declval<int>())) test;
errors with:
error C2661:
std::basic_istream<char,std::char_traits<char>>::operator >>
: no overloaded function takes 2 arguments
The operator>>
that takes an int
is a member function (you're currently using the syntax for both member and nonmember functions) and it takes its argument by reference (so that it can populate it - declval<int>()
gives you an int&&
, you need declval<int&>()
to get an int&
):
using T = decltype(declval<istream>().operator>>(declval<int&>()));
Even better would be to not invoke the operator directly, so you don't have to worry about which operator<<
is a member and which is not:
using T = decltype(declval<istream&>() >> declval<int&>());