473,796 Members | 2,607 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

a manipulator wrapped inside a struct/class does not compile

Hello group, this is my dilemma:
------------------------------------------------------------------------

#include <iostream>

using namespace std;

// a regular manipulator
ostream & hello( ostream & os ) { return os << "regular: hello"; }

struct Test // a manipulator wrapped inside a struct
{
ostream & hello( ostream & os ) { return os << "wrapped: hello"; }
};

int main( )
{
cout << hello << endl; // this works just fine..

Test t;
cout << t.hello << endl; // and this doesn't compile! WHY??

/* note: gcc 2.95.4 says there's no matching function to call,
* and then lists the possible applicators; but there it is:
*
* class ostream & ostream::operat or <<(ostream & (*)(ostream &))
*
* isn't that the wrapped manipulator's signature?
* I don't get it. Would anyone be so kind to explain? thanks!
*/

return 0;
}

Oct 28 '05 #1
8 1799
st****@gmail.co m wrote:
Hello group, this is my dilemma:
------------------------------------------------------------------------

#include <iostream>

using namespace std;

// a regular manipulator
ostream & hello( ostream & os ) { return os << "regular: hello"; }

struct Test // a manipulator wrapped inside a struct
{
ostream & hello( ostream & os ) { return os << "wrapped: hello"; }
A pointer to a function and a pointer to a member function are not
compatible. A manipulator is expected to be a pointer to a function,
not to a member.
};

int main( )
{
cout << hello << endl; // this works just fine..

Test t;
cout << t.hello << endl; // and this doesn't compile! WHY??
Because 't.hello' is a syntax error. You either need 't.hello()' or
'&Test::hello ', to make something of 'hello'. And the second one is not
going to fly due to pointer incompatibility I mentioned above. And the
first one is not what you want.
/* note: gcc 2.95.4 says there's no matching function to call,
* and then lists the possible applicators; but there it is:
*
* class ostream & ostream::operat or <<(ostream & (*)(ostream &))
*
* isn't that the wrapped manipulator's signature?
* I don't get it. Would anyone be so kind to explain? thanks!
*/

return 0;
}


V
Oct 28 '05 #2
> A pointer to a function and a pointer to a member function are not
compatible. A manipulator is expected to be a pointer to a function,
not to a member.
why is that exactly?
Because 't.hello' is a syntax error. You either need 't.hello()' or
'&Test::hello' , to make something of 'hello'. And the second one is not
going to fly due to pointer incompatibility I mentioned above. And the
first one is not what you want.


't.hello()' wouldn't work because the applicator expects a pointer -
not a method.

'&Test::hello ' is a pointer to a class method. That's not what I need.
I have an instance method 'hello'.

I can see 't.hello' is a syntax error, but am curious why this is so.
As far as I can see the compiler is reacting as though 'hello' is of
type 'ostream& (Test::*)( ostream& )', but the 'Test::' part is
irrelevant.. I have dereferenced it with a dot after 't' as in:

struct Test
{
int whatever;
} t;

't.whatever' is of type 'int', not 'Test::int'!
So why isn't 't.hello' of type 'ostream&(*)(os tream&)'? Or even
better.. I believe you understand what kind of use I am aiming at.. is
there a way to circumvent this problem?

Thanks!

Oct 28 '05 #3
st****@gmail.co m wrote:
A pointer to a function and a pointer to a member function are not
compatible. A manipulator is expected to be a pointer to a function,
not to a member.

why is that exactly?


Why is what exactly? I made two statements, which one are you asking about?
Because 't.hello' is a syntax error. You either need 't.hello()' or
'&Test::hello ', to make something of 'hello'. And the second one is not
going to fly due to pointer incompatibility I mentioned above. And the
first one is not what you want.

't.hello()' wouldn't work because the applicator expects a pointer -
not a method.


You can make 'hello' actually return a pointer.
'&Test::hello ' is a pointer to a class method. That's not what I need.
I have an instance method 'hello'.
The term is "non-static member function". Perhaps you should start using
it...
I can see 't.hello' is a syntax error, but am curious why this is so.
Because the language was designed that way.
As far as I can see the compiler is reacting as though 'hello' is of
type 'ostream& (Test::*)( ostream& )', but the 'Test::' part is
irrelevant.. I have dereferenced it with a dot after 't' as in:

struct Test
{
int whatever;
} t;

't.whatever' is of type 'int', not 'Test::int'!
So why isn't 't.hello' of type 'ostream&(*)(os tream&)'?
Because. A function name and an object name behave differently when used
in an expression. You _could_ define 'hello' to be a member of "Test" and
have a type "a pointer to function":

struct Test {
ostream& (*hello)(ostrea m&);
};

which would allow you to use 't.hello' as a stand-alone thing. The value
of it would be used then. Now, how to assign that pointer a particular
value, is another question.
Or even
better.. I believe you understand what kind of use I am aiming at.. is
there a way to circumvent this problem?


See my recommendation above. The trick is still going to be the assignment
of a particular value to 'hello'.

V
Oct 28 '05 #4
st****@gmail.co m wrote:
A pointer to a function and a pointer to a member function are not
compatible. A manipulator is expected to be a pointer to a function,
not to a member.

why is that exactly?


Because a member function has special access to one particular object. A
regular function does not. Of course there is nothing at all to stopyou
writing a regular function which calls a member function, and then you
can use the regular function where you wanted to use the member function.

john
Oct 28 '05 #5

Victor Bazarov wrote:
st****@gmail.co m wrote:
Hello group, this is my dilemma:
------------------------------------------------------------------------

#include <iostream>

using namespace std;

// a regular manipulator
ostream & hello( ostream & os ) { return os << "regular: hello"; }

struct Test // a manipulator wrapped inside a struct
{
ostream & hello( ostream & os ) { return os << "wrapped: hello"; }


A pointer to a function and a pointer to a member function are not
compatible. A manipulator is expected to be a pointer to a function,
not to a member.
};

int main( )
{
cout << hello << endl; // this works just fine..

Test t;
cout << t.hello << endl; // and this doesn't compile! WHY??


Because 't.hello' is a syntax error. You either need 't.hello()' or
'&Test::hello ', to make something of 'hello'. And the second one is not
going to fly due to pointer incompatibility I mentioned above. And the
first one is not what you want.
/* note: gcc 2.95.4 says there's no matching function to call,
* and then lists the possible applicators; but there it is:
*
* class ostream & ostream::operat or <<(ostream & (*)(ostream &))
*
* isn't that the wrapped manipulator's signature?
* I don't get it. Would anyone be so kind to explain? thanks!
*/

return 0;
}


V


Vitya at his finest!!!

Do listen to Victor, I neither had seen this in production not
Victor's code. And I know Victor for quite some time now (Vitya is it
25 or 30 years in total is the duration of our acquaintance and
bestfriendship? ).
Pass my birthday wishes to your sister Dinachka.

Oct 29 '05 #6
> Why is what exactly? I made two statements, which one are you asking about?

I meant.. why aren't a pointer to a function and a pointer to a member
function compatible?
The term is "non-static member function". Perhaps you should start using it...
Perhaps, but English is not my mother tongue so please don't take it
against me. Besides, we've understood eachother just as fine using
these different expressions. Fortunately us humans are far more
flexible than compilers :)

I've tried using the construct with ostream& (*hello)(ostrea m&); you
have proposed
Now, how to assign that pointer a particular value, is another question.


and this turned out to be a rather difficult question! I was unable to
get a hold of the address of my non-static member function :)

Dear Victor (and the rest of the group), I have a feeling you are
keeping some important details to yourself. My question is not an
academic one, but rather a simple design question, a question of
ergonomics if you wish. I would really appreciate your help.

Though discussing language odditys might be fun sometimes, my ultimate
goal is using the class in expressions like this:

MyClass instance;

cout << instance.someth ing << endl;
cout << instance.someth ingElse << endl;

The semantics I'm looking for is that an applicator runs 'something'
and 'somethingElse' in the context of an instance. How can I achieve
this? It doesn't have to be pretty from the inside :)

Thank you Victor, John and others..

Oct 29 '05 #7
st****@gmail.co m wrote:
Why is what exactly? I made two statements, which one are you asking about?

I meant.. why aren't a pointer to a function and a pointer to a member
function compatible?

The term is "non-static member function". Perhaps you should start using it...

Perhaps, but English is not my mother tongue so please don't take it
against me. Besides, we've understood eachother just as fine using
these different expressions. Fortunately us humans are far more
flexible than compilers :)

I've tried using the construct with ostream& (*hello)(ostrea m&); you
have proposed

Now, how to assign that pointer a particular value, is another question.

and this turned out to be a rather difficult question! I was unable to
get a hold of the address of my non-static member function :)

Dear Victor (and the rest of the group), I have a feeling you are
keeping some important details to yourself. My question is not an
academic one, but rather a simple design question, a question of
ergonomics if you wish. I would really appreciate your help.

Though discussing language odditys might be fun sometimes, my ultimate
goal is using the class in expressions like this:

MyClass instance;

cout << instance.someth ing << endl;
cout << instance.someth ingElse << endl;

The semantics I'm looking for is that an applicator runs 'something'
and 'somethingElse' in the context of an instance. How can I achieve
this? It doesn't have to be pretty from the inside :)

Thank you Victor, John and others..


Well here's your problem, you want the return from instance.someth ing()
to be a thing that remembers what instance was so that the thing can
access the context represented by instance.

Now think about what a function is, it is stateless, it cannot remember
any context or anything else. So give up on the idea of
instance.someth ing() returning a function. Instead instance.someth ing()
must return an object.

Something like this (untested)

class MyClass;

class MyManipulator
{
public:
MyManipulator(M yClass* i) : inst(i) {}
MyClass* get_inst() const { return inst; }
private:
MyClass* inst;
};

class MyClass
{
public:
MyManipulator something() { return MyManipulator(t his); }
};

ostream& operator<<(ostr eam& os, const MyManipulator& m)
{
MyInstance* inst = m.get_inst();
// do something with inst
return is;
}

MyClass instance;
cout << instance.someth ing() << endl;

john
Oct 29 '05 #8
Thanks John! Your suggestion pushed me into the right direction. I'll
be exploiting c++'s typesystem to overload (specialize) the
'operator<<' applicator. Basically, I've slightly modified your
solution and generalized it into a template that's simple enough to
use. I'm posting the final solution in case anyone's interested..
---------------------------------------------------------------------------------
#include <iostream>
#include <cstdlib>

using namespace std;

template<class Outer, class TypesystemHook>
class Target
{
Outer& _outer;
public:
Target( Outer& outer ) : _outer( outer ) {}
Outer& operator()( void ) { return _outer; }
};

class MyClass
{
public:

MyClass() : average(*this), sum(*this)
{
for( unsigned int i = 0; i < DataSize; i++ ) { _data[i] =
rand()%20; }
}

Target<MyClass, class Average {}> average;
friend ostream& operator<<( ostream& os, Target<MyClass, Average>& t
)
{
return os << static_cast<dou ble>( t().getSum() ) / DataSize;
}

Target<MyClass, class Sum {}> sum;
friend ostream& operator<<( ostream& os, Target<MyClass, Sum>& t )
{
return os << t().getSum();
}

private:
static const unsigned int DataSize = 10;
int _data[DataSize];

int getSum() // helper
{
int sum = 0;
for( unsigned int i = 0; i < DataSize; i++ ) { sum += _data[i];
}
return sum;
}
};

int main( int argc, char* argv[] )
{
MyClass instance;

cout << instance.sum << endl;
cout << instance.averag e << endl;

return 0;
}
---------------------------------------------------------------------------------
Once again, thank you all for your helpfull suggestions and comments,
John especially!

Oct 30 '05 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
3348
by: rwawryk | last post by:
Hi, Does anybody know how to implement parametrized stream operator (such as setw, setfill)? I need to put into the stream variable of type char* without terminating NULL. It would be great if I had the manipulator which allows to determine maximum number of characters ( let's assume maxw( char* str, int maxlen ) ). example: cout << maxw("Crocodile", 5 );
8
10366
by: Boris | last post by:
Is it possible to manipulate the std::ostream to prepend a string when performing output, e.g. // manipute std::cout to prepend "prefix " std::cout << "hallo" << std::endl; // results in "prefix hallo" I need this to overwrite the "<<" operator for MyClass in a recursive way, e.g.
1
741
by: Bob Rock | last post by:
Hello, in the last few days I've made my first few attempts at creating mixed C++ managed-unmanaged assemblies and looking aftwerwards with ILDASM at what is visible in those assemblies from a managed point-of-view I've noticed that: 1) for each managed and unmanaged C function (not C++ classes) I get a public managed static method (defined on a 'Global Functions' class) in the generated assembly with an export name of the form...
1
3983
by: Bryan Parkoff | last post by:
I know how to write "Pointer to Function" inside struct or class without using static, but I have decided to add static to all functions inside struct or class because I want member functions to be bound inside struct or class to become global functions. It makes easier for me to use "struct.memberfunction()" instead of "globalfunction()" when I have to use dot between struct and member function rather than global function. I do not have...
19
3086
by: Geetesh | last post by:
Recently i saw a code in which there was a structer defination similar as bellow: struct foo { int dummy1; int dummy2; int last }; In application the above array is always allocated at runtime using malloc.In this last member of the structer "int last" is not
6
3596
by: jack | last post by:
I have a class which overloads the insertion operator '<<' for every type that ostream handles. I do this so that I can use my class a direct replacement for cout and cerr where the insertion syntax is used. The reason for this is that I have a log file class that needs to know how many lines have been written. When the line exceeds a certain number, I need to close the log file, and open a new one. I would like to be able to track...
6
1807
by: Roman | last post by:
Hi, Does anyone know why in C++, it is ok to initialize a const static int inside a class, but you can't initialize a float? From what I understand, initialization of const static float can only be done inside a constructor. For example:
5
3744
by: huili80 | last post by:
For example, like in the following, the part commented out was intended as partial spectialzation, but it would even compile. Is it even legal to partially specialize a nested template class inside another template class? template < typename T > struct A { template < typename U > struct B
8
2256
by: Jonathan Sachs | last post by:
I'm trying to compose a list of items, each of which consists of text that wraps around a picture at the left margin. The examples I have seen tell me to do it like this: <p><img src="xxxx.jpg" align="left" width=nn height=nn>zzz zzzzz zz zzzzz...</p> In my case, since the wrapped text includes a headline, I assume I am supposed to do this:
0
10459
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
10187
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9055
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7553
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6795
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5446
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5578
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4120
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
3735
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.