The following code has different compile results. From the error message I'm receiving it seems there's a confusion about operators precedence ()
and <<
. I can easily overcome this issue by using a function. However I would like to understand and to know:
a) Which compiler it's evaluating correctly the expression? MSVC2017 seems more logical to me.
b) Is there an workaround still using MACROs?
Full sample code I used.
#include <cstdlib>
#include <typeinfo>
#include <sstream>
#include <iostream>
#ifndef NDEBUG
#define EXPR_INSPECT(param_)\
( (std::ostringstream{} << "< " #param_ " [" << typeid(param_).name() << "] > : " << param_).str() )
#else
#define EXPR_INSPECT(param_)\
(param_)
#endif //NDEBUG
int main(int argc, char *argv[])
{
auto ull_x {99LLU};
std::string string_x {"Checking..."};
std::cout << EXPR_INSPECT( ull_x) << std::endl;
std::cout << EXPR_INSPECT(string_x) << std::endl;
return EXIT_SUCCESS;
}
MSVC2017 works perfectly!
G++ 8.2.0 (MSYS2/MINGW) issues the following error: 'std::basic_ostream::__ostream_type' {aka 'class std::basic_ostream'} has no member named 'str' Attempts to call str()
on ostream
instead of ostringstream
.
EDIT:
The problem here can also be reproduced by clang using Wandbox. Here is a minimal example:
#include <sstream>
#include <iostream>
int main()
{
auto s = std::ostringstream{};
decltype(((std::ostringstream{}) << "< "))::nothing;
decltype((s << "< "))::nothing;
}
In wandbox, clang found the second type std::basic_ostream
, while the first type std::basic_ostringstream
. That's very strange.