<iostream> query - c++
This is a discussion on <iostream> query - c++ ; Hi thanks to all of you who took the time to share your thought on the
pros/cons of iostream. The enlightened discussion succeed in modifying my
attitude, somewhat and consequently I've been giving the shift operators
some exercise today. And ...
-
<iostream> query
Hi thanks to all of you who took the time to share your thought on the
pros/cons of iostream. The enlightened discussion succeed in modifying my
attitude, somewhat and consequently I've been giving the shift operators
some exercise today. And I've come across this apparent anomaly and I'd be
really pleased if someone could shed light on it.
I get a "C2679: binary '<<' : no operator found which takes a right-hand
operand of type 'MBSPNode<TYPE>' (or there is no acceptable conversion)"
error with this code unless i include an instantiation for MBSPNode ie.
"template MBSPNode<int>" int is just the first type i tried i can still use
the template with any other type and it compiles and works fine but comment
the int instantiation out and 2679 pops up again. Any Ideas cos this is
really annoying me.
Here's the overriden operator for a template
template<class TYPE> class MBSPNode{
friend class MBSPTree;
public:
friend ostream& operator<<(ostream& st, const MBSPNode& nd){ //I
thought this might be wrong but "MBSPNode<TYPE>&" fails too
st << "c_value = " << nd.c_value <<": ";
st << "c_chvIdx = " << nd.c_chvIdx <<": ";
st << "c_prevIdx = " << nd.c_prevIdx <<": ";
return st << "c_nextIdx = " << nd.c_nextIdx << endl;
}
MBSPNode(){
<snip>
}
private:
TYPE c_value;
unsigned long c_nextIdx;
unsigned long c_prevIdx;
unsigned long c_chvIdx;
unsigned long c_count;
};
Heres the code in the container that uses it
template <class TYPE>
void MBSPTree<TYPE>:
ump(ofstream& s){
s << "MBSPTree readable dump" << endl;
unsigned long i = c_lowIdx;
while(i != -1L){
s << "index = " << i << ": ";
s << *c_valList[i]; // c_valList is a granular array of pointers
i = c_valList[i]->c_chvIdx;
}
s.close();
}
-
Re: <iostream> query
mick wrote:
> Hi thanks to all of you who took the time to share your thought on the
> pros/cons of iostream. The enlightened discussion succeed in modifying
> my attitude, somewhat and consequently I've been giving the shift
> operators some exercise today. And I've come across this apparent
> anomaly and I'd be really pleased if someone could shed light on it.
>
> I get a "C2679: binary '<<' : no operator found which takes a
> right-hand operand of type 'MBSPNode<TYPE>' (or there is no acceptable
> conversion)" error with this code unless i include an instantiation
> for MBSPNode ie. "template MBSPNode<int>" int is just the first type i
> tried i can still use the template with any other type and it compiles
> and works fine but comment the int instantiation out and 2679 pops up
> again. Any Ideas cos this is really annoying me.
The problem is that the compiler never automatically causes a member or
friend that was declared within a class to be visible outside the
context of the class.
As the only declaration of your operator<<() is done within the context
of MBSPNode<>, the operator is not visible outside the class.
The easiest way to remedy this, is to move the definition/implementation
of the operator<<() outside the class.
>
> Here's the overriden operator for a template
>
> template<class TYPE> class MBSPNode{
>
> friend class MBSPTree;
>
> public:
Put only the declaration here:
friend ostream& operator<<(ostream&, const MBSPNode&);
> friend ostream& operator<<(ostream& st, const MBSPNode& nd){ //I
> thought this might be wrong but "MBSPNode<TYPE>&" fails too
> st << "c_value = " << nd.c_value <<": ";
> st << "c_chvIdx = " << nd.c_chvIdx <<": ";
> st << "c_prevIdx = " << nd.c_prevIdx <<": ";
> return st << "c_nextIdx = " << nd.c_nextIdx << endl;
> }
And mover this definition outside the class, as:
template <class T>
ostream& operator<<(ostream& st, const MBSPNode<T>& nd){
st << "c_value = " << nd.c_value <<": ";
st << "c_chvIdx = " << nd.c_chvIdx <<": ";
st << "c_prevIdx = " << nd.c_prevIdx <<": ";
return st << "c_nextIdx = " << nd.c_nextIdx << endl;
}
<snip>
Bart v Ingen Schenau
--
a.c.l.l.c-c++ FAQ: http://www.comeaucomputing.com/learn/faq
c.l.c FAQ: http://www.eskimo.com/~scs/C-faq/top.html
c.l.c++ FAQ: http://www.parashift.com/c++-faq-lite/
-
Re: <iostream> query
Bart van Ingen Schenau wrote:
> mick wrote:
>
>> Hi thanks to all of you who took the time to share your thought on the
>> pros/cons of iostream. The enlightened discussion succeed in modifying
>> my attitude, somewhat and consequently I've been giving the shift
>> operators some exercise today. And I've come across this apparent
>> anomaly and I'd be really pleased if someone could shed light on it.
>>
>> I get a "C2679: binary '<<' : no operator found which takes a
>> right-hand operand of type 'MBSPNode<TYPE>' (or there is no acceptable
>> conversion)" error with this code unless i include an instantiation
>> for MBSPNode ie. "template MBSPNode<int>" int is just the first type i
>> tried i can still use the template with any other type and it compiles
>> and works fine but comment the int instantiation out and 2679 pops up
>> again. Any Ideas cos this is really annoying me.
>
> The problem is that the compiler never automatically causes a member or
> friend that was declared within a class to be visible outside the
> context of the class.
Except via ADL, which should apply in this case. Sounds like
one of MSVC++'s known bugs with argument-dependent lookup,
possibly (but I've not checked with either a compiler or the
standard this morning because of time constraints).
-- James
-
Re: <iostream> query
James Dennett wrote:
> Bart van Ingen Schenau wrote:
>> mick wrote:
>>
>>> Hi thanks to all of you who took the time to share your thought on
>>> the pros/cons of iostream. The enlightened discussion succeed in
>>> modifying my attitude, somewhat and consequently I've been giving
>>> the shift operators some exercise today. And I've come across this
>>> apparent anomaly and I'd be really pleased if someone could shed
>>> light on it.
>>>
>>> I get a "C2679: binary '<<' : no operator found which takes a
>>> right-hand operand of type 'MBSPNode<TYPE>' (or there is no
>>> acceptable conversion)" error with this code unless i include an
>>> instantiation for MBSPNode ie. "template MBSPNode<int>" int is just
>>> the first type i tried i can still use the template with any other
>>> type and it compiles and works fine but comment the int
>>> instantiation out and 2679 pops up again. Any Ideas cos this is
>>> really annoying me.
>>
>> The problem is that the compiler never automatically causes a member
>> or friend that was declared within a class to be visible outside the
>> context of the class.
>
> Except via ADL, which should apply in this case.
To my knowledge, even ADL could not have found this overload of
operator<<.
Paragraph 11.4/5 states that a friend function, that is defined within a
class, has the lexical scope of the class. Therefor, the function is
not visible outside the scope of the class (even though the function is
not actually a member).
According to paragraph 3.4.2/1, ADL extends the search for a matching
function to a particular set of namespaces. To my knowledge, these
namespaces do not include the internal scope of any classes involved as
arguments in the function call.
> Sounds like
> one of MSVC++'s known bugs with argument-dependent lookup,
> possibly (but I've not checked with either a compiler or the
> standard this morning because of time constraints).
>
> -- James
Bart van Ingen Schenau
--
a.c.l.l.c-c++ FAQ: http://www.comeaucomputing.com/learn/faq
c.l.c FAQ: http://www.eskimo.com/~scs/C-faq/top.html
c.l.c++ FAQ: http://www.parashift.com/c++-faq-lite/
-
Re: <iostream> query
Bart van Ingen Schenau wrote:
> James Dennett wrote:
>
>> Bart van Ingen Schenau wrote:
>>> mick wrote:
>>>
>>>> Hi thanks to all of you who took the time to share your thought on
>>>> the pros/cons of iostream. The enlightened discussion succeed in
>>>> modifying my attitude, somewhat and consequently I've been giving
>>>> the shift operators some exercise today. And I've come across this
>>>> apparent anomaly and I'd be really pleased if someone could shed
>>>> light on it.
>>>>
>>>> I get a "C2679: binary '<<' : no operator found which takes a
>>>> right-hand operand of type 'MBSPNode<TYPE>' (or there is no
>>>> acceptable conversion)" error with this code unless i include an
>>>> instantiation for MBSPNode ie. "template MBSPNode<int>" int is just
>>>> the first type i tried i can still use the template with any other
>>>> type and it compiles and works fine but comment the int
>>>> instantiation out and 2679 pops up again. Any Ideas cos this is
>>>> really annoying me.
>>> The problem is that the compiler never automatically causes a member
>>> or friend that was declared within a class to be visible outside the
>>> context of the class.
>> Except via ADL, which should apply in this case.
>
> To my knowledge, even ADL could not have found this overload of
> operator<<.
> Paragraph 11.4/5 states that a friend function, that is defined within a
> class, has the lexical scope of the class. Therefor, the function is
> not visible outside the scope of the class (even though the function is
> not actually a member).
> According to paragraph 3.4.2/1, ADL extends the search for a matching
> function to a particular set of namespaces. To my knowledge, these
> namespaces do not include the internal scope of any classes involved as
> arguments in the function call.
friends are special. The Barton-Nackman trick relies on this,
so it survived standardization of C++.
Allow me to restore a little context: here's the definition
we're discussing, slightly edited:
template<class TYPE> class MBSPNode
{
friend class MBSPTree;
public:
friend ostream& operator<<(ostream& st, const MBSPNode& nd){ ... }
MBSPNode(){ }
};
To start with, we have "The name of a friend is not in the
scope of the class". So this isn't about looking in the
scope of the class, for the friend function isn't there.
(Yes, "A friend function defined in a class is in the
(lexical) scope of the class in which it is defined.",
but that doesn't mean that its _name_ is in that scope.)
There's also 14.6.5/2: "As with non-template classes, the
names of namespace-scope friend functions of a class template
specialization are not visible during an ordinary lookup
unless explicitly declared at namespace scope (11.4).
Such names may be found under the rules for associated
classes (3.4.2)"
Right now I can't find the text which does state that this
is true for non-template classes, but I believe that the
*only* way that the operator<< above should be found is by
ADL.
-- James
-
Re: <iostream> query
James Dennett wrote:
> Bart van Ingen Schenau wrote:
>> James Dennett wrote:
>>
>>> Bart van Ingen Schenau wrote:
>>>> mick wrote:
>>>>
>>>>> Hi thanks to all of you who took the time to share your thought on
>>>>> the pros/cons of iostream. The enlightened discussion succeed in
>>>>> modifying my attitude, somewhat and consequently I've been giving
>>>>> the shift operators some exercise today. And I've come across this
>>>>> apparent anomaly and I'd be really pleased if someone could shed
>>>>> light on it.
>>>>>
>>>>> I get a "C2679: binary '<<' : no operator found which takes a
>>>>> right-hand operand of type 'MBSPNode<TYPE>' (or there is no
>>>>> acceptable conversion)" error with this code unless i include an
>>>>> instantiation for MBSPNode ie. "template MBSPNode<int>" int is
>>>>> just the first type i tried i can still use the template with any
>>>>> other type and it compiles and works fine but comment the int
>>>>> instantiation out and 2679 pops up again. Any Ideas cos this is
>>>>> really annoying me.
>>>> The problem is that the compiler never automatically causes a
>>>> member or friend that was declared within a class to be visible
>>>> outside the context of the class.
>>> Except via ADL, which should apply in this case.
>>
>> To my knowledge, even ADL could not have found this overload of
>> operator<<.
>> Paragraph 11.4/5 states that a friend function, that is defined
>> within a class, has the lexical scope of the class. Therefor, the
>> function is not visible outside the scope of the class (even though
>> the function is not actually a member).
>> According to paragraph 3.4.2/1, ADL extends the search for a matching
>> function to a particular set of namespaces. To my knowledge, these
>> namespaces do not include the internal scope of any classes involved
>> as arguments in the function call.
>
> friends are special. The Barton-Nackman trick relies on this,
> so it survived standardization of C++.
>
> Allow me to restore a little context: here's the definition
> we're discussing, slightly edited:
>
> template<class TYPE> class MBSPNode
> {
> friend class MBSPTree;
>
> public:
> friend ostream& operator<<(ostream& st, const MBSPNode& nd){ ...
> }
>
> MBSPNode(){ }
> };
>
> To start with, we have "The name of a friend is not in the
> scope of the class". So this isn't about looking in the
> scope of the class, for the friend function isn't there.
> (Yes, "A friend function defined in a class is in the
> (lexical) scope of the class in which it is defined.",
> but that doesn't mean that its _name_ is in that scope.)
>
> There's also 14.6.5/2: "As with non-template classes, the
> names of namespace-scope friend functions of a class template
> specialization are not visible during an ordinary lookup
> unless explicitly declared at namespace scope (11.4).
> Such names may be found under the rules for associated
> classes (3.4.2)"
I stand corrected.
>
> Right now I can't find the text which does state that this
> is true for non-template classes, but I believe that the
> *only* way that the operator<< above should be found is by
> ADL.
Given the quote above, I do not doubt that corresponding rules exist for
non-template classes.
>
> -- James
Bart v Ingen Schenau
--
a.c.l.l.c-c++ FAQ: http://www.comeaucomputing.com/learn/faq
c.l.c FAQ: http://www.eskimo.com/~scs/C-faq/top.html
c.l.c++ FAQ: http://www.parashift.com/c++-faq-lite/
Similar Threads
-
By Application Development in forum c++
Replies: 0
Last Post: 09-13-2007, 08:55 AM
-
By Application Development in forum c++
Replies: 1
Last Post: 08-21-2007, 03:12 AM
-
By Application Development in forum c++
Replies: 9
Last Post: 08-20-2007, 03:47 PM
-
By Application Development in forum c++
Replies: 4
Last Post: 06-08-2007, 02:44 PM
-
By Application Development in forum c++
Replies: 55
Last Post: 10-01-2006, 05:58 PM