Re: declaring/defining op== for private nested class
Paul Bibbings wrote:
Consider the following sample code and output from an attempt to
compile it:
16:22:28 Paul Bibbings@JIJOU
/cygdrive/d/CPPProjects/nano/test_link $cat test.cpp
// file: test.cpp
#include <string>
template<typename T>
class outer {
public:
explicit outer(T t) : h_(t) { }
bool equals(T t) { return t == h_; } // uses holder::op T&()/T()
private:
struct holder {
explicit holder(T t) : t_(t) { }
operator T&() { return t_; }
operator T() const { return t_; }
T t_;
// friend bool operator==(const T& t, const holder& h) {
// return t == h.t_;
// }
};
holder h_;
};
[snipped]
It seems odd because, though declared as a friend of holder, op== does
not 'require' this friendship in the sense that holder's data is
public. Yet, without defining it as an inline friend I can't see what
other options there are. I'm thinking that it cannot be defined in
the nearest surrounding namespace scope as a non-friend because holder
is a *private* nested class of outer. Furthermore, in real code, I
would want to balance this with its counterparts op==(const holder&,
const T&) and op==(const holder&, const holder&), so it seems that it
must be a free function rather than a member.
So, my question is: is it the language, or is it my understanding,
that is seemingly limiting me in having to provide op== here as an
inline-defined friend of my nested private class.
You could create a base that knows the Holder type.
template<typename T, typename Holder> struct holder_base {
T const& get_t_() const
{ return static_cast<Holder const&>(*this).t_; }
};
template<typename T>
class outer {
public:
explicit outer(T t) : h_(t) { }
bool equals(T t) { return t == h_; }
private:
struct holder : holder_base<T, holder> {
explicit holder(T t) : t_(t) { }
T t_;
};
holder h_;
};
template<typename T, typename Holder>
bool operator==(const T& t, holder_base<T, Holder> const& h)
{
return t == h.get_t_();
}
I don't know tho - this looks worse than the friend function approach you
took above. It's got a higher conversion cost for the second parameter
(derived->base) and some noise around :)
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]