This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

Bug 242438 - Free function friend cannot access private members when templated
Summary: Free function friend cannot access private members when templated
Status: RESOLVED INVALID
Alias: None
Product: cnd
Classification: Unclassified
Component: Code Model (show other bugs)
Version: 7.4
Hardware: Other Linux
: P3 normal (vote)
Assignee: petrk
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-02-28 01:47 UTC by konradsa
Modified: 2014-11-19 19:05 UTC (History)
0 users

See Also:
Issue Type: DEFECT
Exception Reporter:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description konradsa 2014-02-28 01:47:11 UTC
Please have a look at the following code:

#include <iostream>

class B;

template<class T>
class A {
private:
    int var;

    friend std::ostream& operator<<(std::ostream& out, const A<T>& rhs);
    friend B;
};

template<class T>
std::ostream& operator<<(std::ostream& out, const A<T>& rhs) {
    std::cout << rhs.var << std::endl; // parser error here
}

template<class T>
class B {
private:
    A<T> _a;

public:

    void print() {
        std::cout << _a.var << std::endl; // okay
    }
};

The parser highlights an error in the friend function, complaining that it cannot resolve var. If I remove the template parameter from class and function, it works correctly. So it looks like the friend attribute for free functions is not correctly recognized in the presence of templates. Note that it appears to work correctly for friend classes, such as class B.
Comment 1 konradsa 2014-02-28 02:07:24 UTC
Still broken in 8.0 RC1, just tried it out there too.
Comment 2 petrk 2014-11-19 19:05:46 UTC
Sorry, it seems that this code is not correct. If you want to declare non-template friend operator, you have to define non-template operator as well. And vice versa if you declare template function, it cannot be defined by non-template function. In fact your example cannot be built by gcc 4.8.1 (if you will use that operator, otherwise you do not need to have definition of it). Note that not just compiled as compilation phase doesn't include resolving of external references.

To make it more clear:
1) If you will add that code to you sample (and fix forward and friend declarations of 'B'), you won't be able to run it, because linker won't find definition of friend operator '<<'
==========================================
int main() {
    A<int> cls;
    std::cout << cls << std::endl;
    return 0;
}
==========================================
2) To fix that you can modify friend operator declaration in the way below. In that case NetBeans resolves private variable.
==========================================
    template<class U>
    friend std::ostream& operator<<(std::ostream& out, const A<U>& rhs);
==========================================
3) If you want to keep it non-templated, you have to define non-templated operator. In this case for each instantiation of 'A' which is used with std::ostream, you have to provide separate definition of friend operator:
==========================================
std::ostream& operator<<(std::ostream& out, const A<int>& rhs) { // NOTE 'int' HERE
    std::cout << rhs.var << std::endl; // parser error here
}
==========================================