обобщенный оператор C ++ - PullRequest
3 голосов
/ 26 сентября 2011

Я делаю некоторые численные симуляции, где приятно перегрузить операции над векторами (аналогично valarrays). Например, я могу написать

template <typename T>
vector<T> operator*(const vector<T>& A, const vector<T>& B){
   //blah blah
}

Но что, если я хочу обобщить этот шаблон так, чтобы он действовал на два разных типа векторов и (потенциально) возвращал третий тип? То есть Я хочу написать

template <typename T, template U, template V>
vector<V> operator*(const vector<T>& A, const vector<U>& B){
   //blah blah
}

Теперь вышесказанное действительно работает, если я использую оператор в ситуации "A * B", где A и B являются разными типами и возвращают другой отдельный тип. Однако, если A и B имеют одинаковый тип, это не работает. Конечно, я мог бы определить разные шаблоны для каждой комбинации (т.е. только T, или только T и U, или T, U и V), но это кажется уродливым. Есть ли способ, которым я могу использовать одно шаблонное выражение для разновидностей T, U и V, приведенное выше, и заставить его работать, даже если «A», «B» и «A * B» все одинаковые типы (или имеют только 2 разных типа?)

Ответы [ 3 ]

1 голос
/ 26 сентября 2011

Теперь вышесказанное действительно работает, если я использую оператора в ситуации «A * B», где A и B различны и возвращают другой тип.

Если честно, это не имеет смысла. Ваш шаблон не должен работать вообще, потому что V не может быть выведен, и это третий параметр шаблона. Если бы вы написали:

template <typename V, template T, template U>
vector<V> operator*(const vector<T>& A, const vector<U>& B){
   //blah blah
}

Это будет "работать", но только если вы явно указали V, что-то вроде

operator*<double>(A, B); //where A is vector<int> and B is vector<float>, for example

Конечно, вы хотите вернуть vector<V>, где V - это тип выражения T()*U(). Это возможно сделать в C ++ 11, но нетривиально в C ++ 03 (я имею в виду, вы могли бы в лучшем случае выполнить некоторую типизацию). Вот как это делается в C ++ 11:

template <typename T, template U>
vector<decltype(T()*U())> operator*(const vector<T>& A, const vector<U>& B)  
{
   //blah blah
}

НТН

0 голосов
/ 26 сентября 2011

Как уже отмечали другие, вы можете использовать decltype для достижения этой цели. C ++ 0x также предоставляет шаблон common_type, который выводит тип, к которому можно привести все аргументы шаблона без какой-либо конкретной арифметической операции. Поэтому его также можно использовать, если для типов аргументов нет перегруженных операторов.

0 голосов
/ 26 сентября 2011

Это может работать в C ++ 0x с decltype.

template <typename T, template U> 
vector<decltype(declval<T>() + declval<U>())> 
operator*(const vector<T>& A, const vector<U>& B){
   //blah blah
}

Без использования этого механизма - и предполагая, что T и U не предоставляют свой собственный механизм - вы не сможете сделать что-то подобное. Вы можете справиться только с ситуацией, когда T, U и тип возвращаемого значения имеют одинаковый тип. Однако вы можете иметь дело с примитивными типами - есть черта типа Boost для результата применения таких операторов, как +, к различным примитивным типам, чтобы найти продвинутый тип.

...