tags:

views:

65

answers:

6

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?

+2  A: 

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.

AndreyT
+1  A: 

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) {}?

Oli Charlesworth
+2  A: 

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;
}
KennyTM
+2  A: 

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;
Prasoon Saurav
A: 

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

DanDan
+2  A: 

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_;
};
Johannes Schaub - litb
How about `template<typename X> template<typename Y>friend name<X>::operator name<Y>();`, it should work (I haven't tried it yet), right?
Prasoon Saurav
@Prasoon yes that *should* work. See the linked PR against clang. But the Standard's wording for friend declarations in templates is, um, in my opinion very sluggish :) So, I can see why comeau crashes, clang crashes too for a slightly modified example and GCC refuses to accept it :)
Johannes Schaub - litb