Проксимальная причина сообщения об ошибке заключается в том, что, согласно документам , "второй аргумент lazy_enable_if
должен быть типом класса, который определяет вложенный тип с именем type
всякий раз, когда первый параметр (условие) верно ". Это явно не устраивает (если только ваш тип vector
не содержит typedef something type;
).
Вам не нужно lazy_...
здесь. Согласно документации, это необходимо, только если 2-й аргумент может быть неопределенным (например, если 2-й аргумент был typename foo<T>::bar
, а тип bar
определен не для всех типов T
). vector
(что здесь означает vector<T, N>
) всегда будет определяться.
Так что определенно попытайтесь избавиться от lazy_
, или в качестве альтернативы создайте класс черт бездействия template <typename T> struct nop { typedef T type; };
и замените 2-й аргумент на lazy_enable_if_c
на nop<vector>
. Но я думаю, вы уже пробовали первое, по крайней мере. :)
И теперь я понимаю, почему это не сработает. Согласно стандарту 14.7.1 / 1:
Если только шаблон класса
специализация была явно
экземпляр (14.7.2) или явно
специализированный (14.7.3), класс
специализация шаблона неявно
инстанцируется, когда специализация
упоминается в контексте, который
требует полностью определенного объекта
типа или когда полнота
Тип класса влияет на семантику
программа. Неявный
создание шаблона класса
специализация вызывает неявное
создание деклараций, но
не из определений или по умолчанию
аргументы члена класса
функции, классы-члены, статические данные
элементы и шаблоны участников;
Таким образом, все, что вызывает создание экземпляра класса, будет пытаться создавать объявления для всех методов, которые завершатся неудачно, когда N != 3
. Похоже, вам нужно использовать всегда присутствующий метод, который вместо этого передает шаблон функции. Не волнуйтесь, любой приличный компилятор все еще сможет встроить это:
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);
}
};
Это будет работать, потому что функция-член определений не создается, если они не были фактически вызваны (или их адреса не получены)