Detecting ostream manipulators

L

Lionel B

In an overloaded output operator for a class I want to detect ostream manipulators such as flush, endl, ends, etc. I am
stymied by how to do this; here's a minimal program indicating my problem:

// test.cpp

#include <iostream>

void foo(std::eek:stream& (*f)(std::eek:stream&))
{
if (f == &std::endl) std::cout << "Detected 'endl'\n"; // line 5
}

int main()
{
foo(std::endl);
return 0;
}

// test.cpp

g++ (3.4.1) barfs on this with:

g++ -W -Wall test.cpp -o test.exe
test.cpp: In function `void foo(std::eek:stream&(*)(std::eek:stream&))':
test.cpp:5: error: address of overloaded function with no contextual type information

at the indicated line. I don't quite see what more information the compiler should need to resolve the address of
std::endl. I realize that std::endl is templated, but surely it should be able to resolve the overload from the type of
the f argument to foo()...?
 
L

Lionel B

Lionel said:
In an overloaded output operator for a class I want to detect ostream
manipulators such as flush, endl, ends, etc. I am stymied by how to
do this; here's a minimal program indicating my problem:

// test.cpp

#include <iostream>

void foo(std::eek:stream& (*f)(std::eek:stream&))
{
if (f == &std::endl) std::cout << "Detected 'endl'\n"; // line 5
}

int main()
{
foo(std::endl);
return 0;
}

// test.cpp

g++ (3.4.1) barfs on this with:

g++ -W -Wall test.cpp -o test.exe
test.cpp: In function `void foo(std::eek:stream&(*)(std::eek:stream&))':
test.cpp:5: error: address of overloaded function with no
contextual type information

at the indicated line. I don't quite see what more information the
compiler should need to resolve the address of std::endl. I realize
that std::endl is templated, but surely it should be able to resolve
the overload from the type of the f argument to foo()...?

This compiles (and works correctly) if I cast std::endl explicitly, so that the comparison becomes:

if (f == static_cast<std::eek:stream& (*)(std::eek:stream&)>(std::endl))

I still can't see why this should be necessary and am beginning to suspect a gcc quirk. I'd be interested if anyone can
compile/test my original code with a different compiler...
 
D

davidrubin

void foo(std::eek:stream& (*f)(std::eek:stream&))
{
if (f == &std::endl) std::cout << "Detected 'endl'\n"; // line 5
}
[snip]
This compiles (and works correctly) if I cast std::endl explicitly, so that the comparison becomes:

if (f == static_cast<std::eek:stream& (*)(std::eek:stream&)>(std::endl))

FWIW, you are comparing '&std::endl' in the first case and 'std::endl'
in the second. Although these expressions have the same value, they
apparantly do not have the same type.

/david
 
L

Lionel B

void foo(std::eek:stream& (*f)(std::eek:stream&))
{
if (f == &std::endl) std::cout << "Detected 'endl'\n"; // line 5
}
[snip]
This compiles (and works correctly) if I cast std::endl explicitly,
so that the comparison becomes:

if (f == static_cast<std::eek:stream&
(*)(std::eek:stream&)>(std::endl))

FWIW, you are comparing '&std::endl' in the first case and 'std::endl'
in the second. Although these expressions have the same value, they
apparantly do not have the same type.

Maybe, but I don't think that really explains the problem:

if (f == static_cast<std::eek:stream& (*)(std::eek:stream&)>(&std::endl)) ...

(i.e. casting &std::endl) works just as well, while:

if (f == std::endl) ...

actually gives a different error:

test.cpp:5: error: assuming cast to type `std::basic_ostream said:
&(*)(std::basic_ostream<char, std::char_traits<char> >&)' from overloaded function

i.e. it seems to be complaining about a type mismatch. FWIW:

if (*f == std::endl) ...

gives the same error as above... still puzzled.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,825
Latest member
VernonQuy6

Latest Threads

Top