0

float과 같은 스칼라 유형에서도 작동하는 맞춤 데이터 유형에 대한 특수 '최대'(즉 최대) 함수를 구현하는 방법에 대한 조언을 찾고 있습니다. 필자가 쓰고있는 데이터 형식은 벡터의 래퍼 (결국 std::vector이 아닌 4 개의 부동 소수점을 나타내는 SIMD 벡터)이며 두 벡터를 비교하고 각 요소의 최대 값 인 새 벡터를 반환하는 max 함수를 제공하려고합니다. . 비교 연산자를 사용하는 std::max과는 다르지만 개념은 같습니다.C++ - 비교 연산자를 오버로드하지 않고 std :: max에 대한 사용자 지정 형식을 특수화하는 방법?

문제는 입력에 max을 적용하는 do_max(T x, T y)이라는 일반 함수가 있다는 것입니다. 스칼라 부동 입력 (예 : do_max<float>(0.1f, 0.2f)) 내 벡터 클래스 (예 : do_max<MyVector>(v0, v1)) 모두에서 작동하려면이 함수가 필요합니다.

MyVector의 비교 연산자에 과부하가 걸리는 것은 SIMD 내장 함수가있는 SIMD 내장 함수를 사용하기 때문에 옵션이 아닙니다. 부울 값을 반환하지 않고 각 요소 비교에 1, 0, -1이 포함 된 정수 벡터를 만듭니다 결과.

// 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; 
} 
내가 스칼라 유형 std::max 해당 max 기능 결의를 할 수있는 방법이 필요 느낌이

, 내 전문 : 당신이 float f0 = ... 줄을 주석으로하지 않는

내가 아래에있는 코드는 컴파일되지 않습니다 max MyVector 유형의 친구 기능.

어떻게 이런 식으로 작동하는 max 함수를 정의 할 수 있습니까? std::max을 잊어 버리고 MyVector에 특화된 자체 최대 함수를 사용하고 float과 같은 스칼라 유형을 구현하는 것이 더 낫지 않습니까?

이 배경은 MyVector 및 스칼라 유형 (컴파일 타임에 매개 변수화 된 유형)과 함께 작동하는 데이터 경로를 구현한다는 것입니다. 나는 이미 산술 연산을 수행하지만, max에 대한 솔루션은 min, exp, pow과 같은 다른 함수에도 사용됩니다.

답변

7

클래식 솔루션 :

template<typename T> 
T do_max(const T & x, const T & y) { 
    using std::max; 
    return max(x, y); 
} 

인수 종속 조회가 float이 발생하지 않습니다 그리고 당신은 std::max<float>를 얻을, 당신의 max 찾습니다.

+0

고마워요, 저의 경우에 효과가 있습니다. – meowsqueak

+0

'return max (x, y)'를'return max (x, y)'로 바꾸면 이것이 실패하는 이유를 알고 계십니까? 이 경우 컴파일러는'std :: max (x, y)'에 대한 호출로 해석하고'do_max '이 인스턴스화 될 때'<'연산자에 대한 유효하지 않은 피연산자로 실패하는 것처럼 보입니다. 나는 왜 'max'에 명시 적으로 타입 매개 변수를 만들면이 동작을 바꿀지 이해하지 못합니다. – meowsqueak

+1

함수가 템플릿이 아닙니까? 최대 은 명시 적 템플릿 인스턴스입니다. – MSalters

관련 문제