Re: how to avoid instantiation of template operator?
Michael Kilburn schrieb:
Basically, this operator==:
template<class T> class accessor {
typedef accessor<T> Self;
public:
template<class C> friend inline bool operator==(Self l, C& r)
{ return l.m_ref == r; }
};
should not be instantiated if 'l.m_ref == r' fails to compile due to,
for example, absence of related operator==.
Unfortunately your snippet misses some clarifications,
the obvious one is that it is not clear, what type m_ref
belongs to, because its not defined above. In the following
I assume that m_ref has type T.
The code should solve your problem, I guess. It works for
Comeau 4.3.8 ALPHA, VS2003, VS2005-SP1, and mingw
with gcc 3.4.
template <bool Enable, typename T = void>
struct enable_if {
typedef T type;
};
template <typename T>
struct enable_if<false, T> {
};
namespace Details {
struct Shim
{
Shim(...); // Can be implicitely constructed by
// everything (Not defined).
};
struct NoMatchType
{
};
// Only declared, never defined:
NoMatchType operator==(const Shim&, const Shim&);
template <typename T, typename U>
struct IsEqualComparableImpl
{
private:
static const T& t();
static const U& u();
static char Check(bool); // Expected result
static char (&Check(const NoMatchType&))[2]; // Fallback
public:
static const bool value = sizeof(Check(t() == u())) == 1;
};
}
template <typename T, typename U>
struct IsEqualComparable {
static const bool value =
Details::IsEqualComparableImpl<T, U>::value;
};
template<class T> class accessor {
typedef accessor<T> Self;
public:
accessor() : m_ref() {}
template<class C> friend
inline
typename enable_if<IsEqualComparable<T, C>::value,
bool>::type
operator==(Self l, C& r) {
return l.m_ref == r;
}
private:
T m_ref;
};
class C{};
class D {};
bool operator==(D, D) { return true; }
bool test() {
accessor<D> a1;
D d;
bool b = a1 == d; // OK
accessor<int> a;
C c;
return a == c; // Error
}
int main() {
return test();
}
Greetings from Bremen,
Daniel Kr|gler
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]