rahul garg
rahul garg

Reputation: 61

cannot access private member declared in class error while instantiating template

My code is as follows

template <typename T>

class name
{
public:
    name() : h_(0){}

    template <typename U>
    operator name<U>()
    {
        name<U> u;
        u.h_ = h_;
        return u;
    }
private:
    int h_;
};

int main(void)
{
    name<int> a;
    name<double> b = a;
    return 0;
}

The error that I get is int name<double>::h_ is private. How to fix the error?

Upvotes: 6

Views: 3776

Answers (6)

Oliver Charlesworth
Oliver Charlesworth

Reputation: 272822

You'll need to add setters/getters (or friendship, or something else). The problem is that name<T> and name<U> are completely unrelated classes.

Alternatively, why don't you just add another constructor name(const T &h) : h_(h) {}?

Upvotes: 1

AnT stands with Russia
AnT stands with Russia

Reputation: 320787

name<T> and name<U> are seen by the compiler as two different classes, amd it doesn't allow you to access private members of the other class. How to fix it? Either redesign or grant friendship. Or provide accessor... There are many ways to do it, the most appropriate one one depends on your intent. If I guess your intent correctly, granting friendship might be a good idea, but I can't see the whole picture from the code you posted.

Upvotes: 2

Johannes Schaub - litb
Johannes Schaub - litb

Reputation: 507423

name<int> tries to access a private member of name<double>. You should be able to fix it by making the conversion function a friend, but compilers I tried go havoc if you try.

You could also make any name<T> a friend of name<U> to fix this.

template <typename T>
class name
{
public:
    name() : h_(0){}

    template <typename U>
    operator name<U>()
    {
        name<U> u;
        u.h_ = h_;
        return u;
    }

    template<typename U>
    friend class name; // <----

private:
    int h_;
};

Upvotes: 3

DanDan
DanDan

Reputation: 10562

Name<T> is potentially a different type to Name<U>, so the rules of encapsulation apply. Use accessors or friends.

Upvotes: 0

Prasoon Saurav
Prasoon Saurav

Reputation: 92942

name<T> can be different from name<U>[for example: in your case]. Hence one cannot access the private members of the other [in case T and U are different types].

Add the following to your class definition.

template<typename U>
 friend class name;

Upvotes: 1

kennytm
kennytm

Reputation: 523794

name<int> and name<double> are different instantiations, and thus are actually different classes. Their private members cannot be shared by default. You need to make name<T> friend to all other name's.

template <typename T>

class name
{
public:
    name() : h_(0){}

    template <typename U>
    operator name<U>()
    {
        name<U> u;
        u.h_ = h_;
        return u;
    }
private:
    int h_;
    template <typename>   // <--
    friend class name;   // <--
};

int main(void)
{
    name<int> a;
    name<double> b = a;
    return 0;
}

Upvotes: 7

Related Questions