The proximal cause of the error message is that, according to the docs, "The second argument of lazy_enable_if
must be a class type that defines a nested type named type
whenever the first parameter (the condition) is true." That's clearly not satisfied here (unless your vector
type just happens to contain typedef something type;
).
You don't need lazy_...
here. According to the docs, that's only needed if the 2nd arg could be undefined (e.g. if the 2nd arg was typename foo<T>::bar
, and the bar
type is not defined for all types T
). vector
(which here means vector<T, N>
) will always be defined.
So definitely try getting rid of lazy_
, or alternatively create a do-nothing traits class template <typename T> struct nop { typedef T type; };
and replace the 2nd arg to lazy_enable_if_c
with nop<vector>
. But my guess is you've already tried the former at least. :)
And now I see why that won't work. According to the standard 14.7.1/1:
Unless a class template
specialization has been explicitly
instantiated (14.7.2) or explicitly
specialized (14.7.3), the class
template specialization is implicitly
instantiated when the specialization
is referenced in a context that
requires a completely-defined object
type or when the completeness of the
class type affects the semantics of
the program. The implicit
instantiation of a class template
specialization causes the implicit
instantiation of the declarations, but
not of the definitions or default
arguments, of the class member
functions, member classes, static data
members and member templates;
So anything that causes the class to be instantiated will try to instantiate declarations for all methods, which will fail when N != 3
. So it looks like you'll need to use an always-present method that hands off to a function template instead. Don't worry, any decent compiler will still be able to inline through this:
template< typename T, unsigned N > class vector; // Fwd decl.
template< typename T, unsigned N >
inline boost::enable_if_c< (N == 3), vector<T, N> >::type
magic(const vector<T, N>& lhs, const vector<T, N>& rhs) {
/* Do the calculation as before... */
return ret;
}
template< typename T, unsigned N >
class vector {
...
inline vector operator ^(const vector &rhs) const {
return magic(*this, rhs);
}
};
This will work because the member function definitions are not instantiated unless they are actually called (or their addresses are taken etc.).