Это хитрость для ограничения шаблонов функций - для ограничения класса типов. Существует множество концепций, таких как векторное выражение, скалярное выражение, матричное выражение и т. Д. Если вы хотите написать шаблон функции, который умножает вектор на скаляр, вы можете попробовать написать
template<typename V, typename S>
some_type operator*(V v, S s); // vector * scalar
template<typename V, typename S>
some_type operator*(S s, V v); // scalar * vector
но это не сработает, потому что оба объявления по существу эквивалентны, и никто не сказал, что V должен быть векторным выражением, а S - скалярным выражением. Итак, разработчики uBlas использовали CRTP для ограничения этих шаблонов:
template<typename V, typename S>
some_Type operator*(vector_expression<V> ve, scalar_expression<S> se);
Чтобы это работало, все скалярные выражения S должны быть производными от scalar_expression<S>
, а все векторные выражения V должны быть производными от vector_expression<V>
. Таким образом, этот оператор рассматривается только в том случае, если первый операнд действительно является выражением для вектора, а второй аргумент действительно является выражением для скаляра. Вы можете перегрузить этот шаблон функции вторым, который меняет оба параметра, и все в порядке.
Теперь, чтобы иметь доступ к чему-либо из V и S (производных типов), нам нужно преобразование из базового класса в производный класс. Для этого и предназначен оператор преобразования в базовом классе. Поскольку базовый класс знает производный класс (это параметр шаблона), это не проблема. Имеет смысл выбрать самый слабый оператор приведения, который позволяет при этом избегать ошибок. Это static_cast
. Он может использоваться для преобразования базы * в производную * без каких-либо существенных накладных расходов.
Я не понимаю, что вы пытаетесь сделать со своим кодом
template<class E>
class vector_expression2 : private vector_expression<E>;
Если вы хотите написать собственное векторное выражение в качестве шаблона, вы должны сделать это так:
template<class E>
class my_parameterized_vector_expression
: public vector_expression<my_parameterized_vector_expression<E> >;
Я не думаю, что это работает с частным наследованием. По крайней мере, все шаблоны функций, которые принимают выражение вектора в качестве аргумента, не смогут получить доступ к оператору преобразования из базового класса, если вы здесь используете частное наследование.