Я ищу советы о том, как реализовать (максимум т.е.) функция для типа данных пользовательского который также работает со скалярными типами, как float
специализированной «макс». Тип данных Я пишу это обертка для вектора (в конце концов, вектор SIMD из четырех поплавков, а не std::vector
), и я хочу, чтобы обеспечить max
функции сравнением двух векторов и возвращает новый вектор, максимум каждого элемента , Это отличается от std::max
, который использует оператор сравнения, но концепция одинаков.C++ - Как специализировать настраиваемый тип для std :: max без перегрузки операторов сравнения?
Проблема в том, что у меня есть общая функция, называемая do_max(T x, T y)
, которая применяет max
к входам. Мне нужна эта функция работать как для скалярных флоат входов (например do_max<float>(0.1f, 0.2f)
) и мой вектор класса (например, do_max<MyVector>(v0, v1)
).
Обратите внимание, что перегрузка операторов сравнения MyVector не является опцией, потому что я использую те, у которых с SIMD-интерфейсами совершенно разные: они создают целочисленный вектор, содержащий 1, 0, -1 для каждого сравнения элементов, а не возвращают логическое результат.
код у меня ниже не компилируется, если вы закомментировать float f0 = ...
строки:
// compile with: g++ -std=c++11 max.cc -o max
#include <algorithm>
#include <vector>
class MyVector {
public:
MyVector(float x0, float x1, float x2, float x3) : storage_ { x0, x1, x2, x3 } {};
friend MyVector max(MyVector lhs, const MyVector & rhs);
private:
std::vector<float> storage_;
};
MyVector max(MyVector lhs, const MyVector & rhs) {
for (size_t i = 0; i < lhs.storage_.size(); ++i) {
lhs.storage_[i] = std::max(lhs.storage_[i], rhs.storage_[i]);
}
return lhs;
}
template<typename T>
T do_max(const T & x, const T & y) {
// if this is std::max then it won't compile for MyVector
return max(x, y);
}
int main(int argc, char * argv[]) {
MyVector v0 { 0.1, 0.2, 0.3, 0.4 };
MyVector v1 { 0.4, 0.3, 0.2, 0.1 };
MyVector v2 = do_max(v0, v1);
// Comment out the following line to successfully compile.
// However I'd like this to work for scalar types too:
float f0 = do_max(0.1f, 0.2f);
return 0;
}
У меня есть чувство, что я нужен способ, чтобы сделать эту max
функции решимость std::max
для скалярных типов, и мои специализированное max
Функция друга для типа MyVector.
Как я определить функцию максимального, которая работает таким образом? Лучше ли забыть о std::max
и использовать мою собственную функцию max, которая специализируется на MyVector
, а также обеспечивает реализацию для таких скалярных типов, как float
?
Предпосылкой этого является то, что я реализует путь данных, я надеюсь, будет работать как с MyVector и скалярных типов (как параметризованные типа во время компиляции). У меня уже есть арифметическая работа, однако решение для max
будет использоваться с другими функциями, такими как min
, exp
, pow
.
Спасибо, что работает для моего примера. – meowsqueak
Знаете ли вы, почему это не удается, если я заменил 'return max (x, y)' на 'return max (x, y)'? В этом случае, это выглядит как компилятор решает это как вызов 'станд :: макс (х, у)' и не с некорректными операндами к '' <оператору, когда '' do_max конкретизируются. Я не понимаю, почему изменение типа параметра на 'max' изменило бы это поведение. –
meowsqueak
Ваша функция не является шаблоном? max - это явное создание шаблона. –
MSalters