Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > nonmember functions?

Reply
Thread Tools

nonmember functions?

 
 
desktop
Guest
Posts: n/a
 
      05-23-2007
I have read that the allocator class has the following nonmember functions:

template <class In, class For> For uninitialized_copy(In,In,For);
template <class For, class T>
void uninitialized_fill(For, For, const T&);

But what does it mean that the two functions are nonmembers? Are they
defined outside the class declaration in the header file?
 
Reply With Quote
 
 
 
 
Fei Liu
Guest
Posts: n/a
 
      05-23-2007
desktop wrote:
> I have read that the allocator class has the following nonmember functions:
>
> template <class In, class For> For uninitialized_copy(In,In,For);
> template <class For, class T>
> void uninitialized_fill(For, For, const T&);
>
> But what does it mean that the two functions are nonmembers? Are they
> defined outside the class declaration in the header file?


It means the 2 functions are not members of the allocator class. They
could be declared as friend functions of the allocator class. As to
definition, they can be either inside or outside of the class declaration.

F
 
Reply With Quote
 
 
 
 
Howard
Guest
Posts: n/a
 
      05-23-2007

"Fei Liu" <(E-Mail Removed)> wrote in message
news:f326s4$j0b$(E-Mail Removed)...
> desktop wrote:
>> I have read that the allocator class has the following nonmember
>> functions:
>>
>> template <class In, class For> For uninitialized_copy(In,In,For);
>> template <class For, class T>
>> void uninitialized_fill(For, For, const T&);
>>
>> But what does it mean that the two functions are nonmembers? Are they
>> defined outside the class declaration in the header file?

>
> It means the 2 functions are not members of the allocator class. They
> could be declared as friend functions of the allocator class.


They could be. They don't have to be. If the class has no private or
protected members which the functions need access to, then there's no need
to write friend declarations for them in the allocator class.

> As to definition, they can be either inside or outside of the class
> declaration.
>


Eh? How can you define a non-member function *inside* the class? Simply
declaring it inside the class (let alone defining it), makes it a member
function. (Unless, of course, you're talking about a friend declaration.
But that's still just a friend declaration, not a function definition.)

-Howard


 
Reply With Quote
 
Marcus Kwok
Guest
Posts: n/a
 
      05-23-2007
Howard <(E-Mail Removed)> wrote:
> Eh? How can you define a non-member function *inside* the class? Simply
> declaring it inside the class (let alone defining it), makes it a member
> function. (Unless, of course, you're talking about a friend declaration.
> But that's still just a friend declaration, not a function definition.)


Like this:

#include <iostream>

class Foo {
public:
Foo() : i_(42) { }

friend void print(const Foo& f)
{
std::cout << f.i_ << '\n';
}

private:
int i_;
};

int main()
{
Foo f;
print(f);
//f.print();
}


Uncomment f.print() to get a compilation error saying that print() is
not a member of Foo, but print() is defined inside the class.

--
Marcus Kwok
Replace 'invalid' with 'net' to reply
 
Reply With Quote
 
Pete Becker
Guest
Posts: n/a
 
      05-23-2007
desktop wrote:
> I have read that the allocator class has the following nonmember functions:
>
> template <class In, class For> For uninitialized_copy(In,In,For);
> template <class For, class T>
> void uninitialized_fill(For, For, const T&);
>
> But what does it mean that the two functions are nonmembers? Are they
> defined outside the class declaration in the header file?


It's a bit misleading. They're non-member functions in the sense that
they aren't member functions of any class. But they have no special
relationship to allocators. They're general purpose algorithms that
happen to be useful for allocators among other things.

--

-- Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." (www.petebecker.com/tr1book)
 
Reply With Quote
 
Howard
Guest
Posts: n/a
 
      05-23-2007

"Marcus Kwok" <(E-Mail Removed)> wrote in message
news:f32bip$703$(E-Mail Removed)...
> Howard <(E-Mail Removed)> wrote:
>> Eh? How can you define a non-member function *inside* the class? Simply
>> declaring it inside the class (let alone defining it), makes it a member
>> function. (Unless, of course, you're talking about a friend declaration.
>> But that's still just a friend declaration, not a function definition.)

>
> Like this:
>
> #include <iostream>
>
> class Foo {
> public:
> Foo() : i_(42) { }
>
> friend void print(const Foo& f)
> {
> std::cout << f.i_ << '\n';
> }
>
> private:
> int i_;
> };
>
> int main()
> {
> Foo f;
> print(f);
> //f.print();
> }
>
>
> Uncomment f.print() to get a compilation error saying that print() is
> not a member of Foo, but print() is defined inside the class.
>


Interesting. Can't say as I've ever seen a friend function actually
*defined* inside a class. Is it portable? (It looks like this may be
related to a recent discussion about "injecting" a function into a namespace
via a friend declaration.) How is it affected by the visibility within that
class? Would it have to be in the a public section to be seen from outside,
even though it's not a member? Can it be specified via
Foo:rint(whatever), or is it just a member of the enclosing namespace?

-Howard


 
Reply With Quote
 
Marcus Kwok
Guest
Posts: n/a
 
      05-24-2007
Howard <(E-Mail Removed)> wrote:
> "Marcus Kwok" <(E-Mail Removed)> wrote in message
> news:f32bip$703$(E-Mail Removed)...
>> Howard <(E-Mail Removed)> wrote:
>>> Eh? How can you define a non-member function *inside* the class? Simply
>>> declaring it inside the class (let alone defining it), makes it a member
>>> function. (Unless, of course, you're talking about a friend declaration.
>>> But that's still just a friend declaration, not a function definition.)

>>
>> Like this:
>>
>> #include <iostream>
>>
>> class Foo {
>> public:
>> Foo() : i_(42) { }
>>
>> friend void print(const Foo& f)
>> {
>> std::cout << f.i_ << '\n';
>> }
>>
>> private:
>> int i_;
>> };
>>
>> int main()
>> {
>> Foo f;
>> print(f);
>> //f.print();
>> }

>
> Interesting. Can't say as I've ever seen a friend function actually
> *defined* inside a class. Is it portable? (It looks like this may be
> related to a recent discussion about "injecting" a function into a namespace
> via a friend declaration.)


I can't say with 100% certainty, but I think it is. I first saw this
technique in a post here a while ago, but with a friend operator<<, and
nobody called him out on it.

> How is it affected by the visibility within that
> class? Would it have to be in the a public section to be seen from outside,
> even though it's not a member?


I tried putting it in the private section and it still worked.

> Can it be specified via
> Foo:rint(whatever), or is it just a member of the enclosing namespace?


I tried using it as Foo:rint() and I got a compilation error saying
that print() is not a member of Foo, which makes sense since it is not a
class static function. Therefore, I would say that it is just a member
of the enclosing namespace.

--
Marcus Kwok
Replace 'invalid' with 'net' to reply
 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      05-25-2007
On May 23, 11:55 pm, "Howard" <(E-Mail Removed)> wrote:
> "Marcus Kwok" <(E-Mail Removed)> wrote in message
> news:f32bip$703$(E-Mail Removed)...
> > Howard <(E-Mail Removed)> wrote:
> >> Eh? How can you define a non-member function *inside* the class? Simply
> >> declaring it inside the class (let alone defining it), makes it a member
> >> function. (Unless, of course, you're talking about a friend declaration.
> >> But that's still just a friend declaration, not a function definition.)


> > Like this:


> > #include <iostream>


> > class Foo {
> > public:
> > Foo() : i_(42) { }


> > friend void print(const Foo& f)
> > {
> > std::cout << f.i_ << '\n';
> > }


> > private:
> > int i_;
> > };


> > int main()
> > {
> > Foo f;
> > print(f);
> > //f.print();
> > }


> > Uncomment f.print() to get a compilation error saying that print() is
> > not a member of Foo, but print() is defined inside the class.


> Interesting. Can't say as I've ever seen a friend function actually
> *defined* inside a class. Is it portable?


[I thought I'd already answered this, but I don't see my
posting...]

It's a fairly well known idiom, first published, I think, by
Barton and Nackman. The committee took it into consideration
when changing the rules for name lookup; even then, breaking it
was considered to be something that would break too much code.

> (It looks like this may be
> related to a recent discussion about "injecting" a function into a namespace
> via a friend declaration.)


Yup. Historically, it worked because friend names were injected
into the surrounding namespace scope (or file scope, given that
namespaces didn't exist). This injection caused problems
elsewhere (I forget what), and the committee did away with it.
But only because ADL could now be used to find the name.

Note that there are special cases which were broken. Consider
the following:

class A {} ;

class B
{
public:
B( A const& ) {}
friend void print( B const& ) {}
} ;

int main()
{
A anA ;
print( anA ) ;
return 0 ;
}

According to the old (pre-199 rules, this is legal; print is
injected into the global namespace, name lookup in main finds
it, and overload resolution uses the convertion constructor to
convert the argument and call it. Under the new rules, there is
nothing in the arguments which relates to B, so the compiler
does not look there in ADL, and so the code fails to compile.

Many compilers (VC++ 8, Sun CC 5.8, g++ pre-4.0) still implement
friend injection; of the compilers I have access to, the only
one which complains about this code is g++ 4.1.0.

> How is it affected by the visibility within that
> class?


I think you mean access control. Visibility is a rather vague
term, related to name look up, and everything in a class
definition has the same "visibility". Access control (public,
private, etc.) only affects members, and a friend is not a
member.

> Would it have to be in the a public section to be seen from outside,
> even though it's not a member?


No.

Think about it for a minute. I can also declare the friend
outside of the class. Should it be accessible then, but not if
I don't.

A friend is not a member. Given something like:

namespace A {
class B {
friend void f() ;
} ;
}

The function declared by the friend declaration is A::f(), not
A::B::f(). Regardless of where it is defined. "Visibility"
(i.e. whether name lookup will find the symbol or not),
membership and access control or largely orthogonal issues. In
the example immediately above, f() is a member of A, and it's
fully qualified name is A::f(). It is, however, only visible in
contexts where name lookup looks into B: in member functions of
B, or when ADL kicks in for B. (Theoretically, it's also
visible in contexts like "someB.f()", after the dot. But in
those contexts, only members are considered, and since it's not
a member...)

Access control only affects members, and it is only applied
after name lookup and overload resolution have taken place; if
overload resolution chooses a private function, it's an error,
even if there is a public function of the same name which could
be called.

> Can it be specified via
> Foo:rint(whatever), or is it just a member of the enclosing namespace?


It's just a member of the enclosing namespace. Even though it
isn't visible there.

--
James Kanze (GABI Software) email:(E-Mail Removed)
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

 
Reply With Quote
 
Gennaro Prota
Guest
Posts: n/a
 
      05-25-2007
On 25 May 2007 00:05:16 -0700, James Kanze wrote:

>Note that there are special cases which were broken. Consider
>the following:
>
> class A {} ;
>
> class B
> {
> public:
> B( A const& ) {}
> friend void print( B const& ) {}
> } ;
>
> int main()
> {
> A anA ;
> print( anA ) ;
> return 0 ;
> }
>
>According to the old (pre-199 rules, this is legal; print is
>injected into the global namespace, name lookup in main finds
>it, and overload resolution uses the convertion constructor to
>convert the argument and call it. Under the new rules, there is
>nothing in the arguments which relates to B, so the compiler
>does not look there in ADL, and so the code fails to compile.
>
>Many compilers (VC++ 8, Sun CC 5.8, g++ pre-4.0) still implement
>friend injection; of the compilers I have access to, the only
>one which complains about this code is g++ 4.1.0.


And in the serious, responsible, tradition of g++ there's a temporary
option, -ffriend-injection, which can help in the transition:

<http://gcc.gnu.org/gcc-4.1/changes.html>

--
Gennaro Prota -- C++ Developer, For Hire
https://sourceforge.net/projects/breeze/
(please check 'Status <date>' link in Summary page)
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
nonmember function swap used in assignment ma740988@gmail.com C++ 2 10-02-2005 01:50 PM
nonmember function bluekite2000@gmail.com C++ 3 08-03-2005 01:41 PM
Do nonmember nonfriend functions improve genericity? bluekite2000@gmail.com C++ 1 07-29-2005 05:00 PM
nonmember vs member? Erik Haugen C++ 13 10-24-2003 08:06 PM



Advertisments