ProgramingTip

std :: minmax (a, b)를 std :: tie (a, b)에 할당하는 좋은 방법이 있습니까?

bestdevel 2021. 1. 7. 21:29
반응형

std :: minmax (a, b)를 std :: tie (a, b)에 할당하는 좋은 방법이 있습니까?


std::tie(a, b) = std::minmax(a, b);

다음 인 코드라고 생각합니다. 깨끗하고 신뢰할 수 있습니다. 안타깝게도 .NET 용 템플릿 처럼 의도 한대로 작동하지 않습니다 . 따라서 값이 둘 이상의 할당 내에서 교체 되면 다른 값을 사용합니다.std::minmaxconst&std::pair<const&, const&>

auto[a, b] = std::make_pair(7, 5);

std::tie(a, b) = std::minmax(a, b);

std::cout << "a: " << a << ", b: " << b << '\n';

a : 5, b : 5

여기서 예상되는 출력은 a: 5, b: 7입니다.


일부 범위에 함수를 적용하기 변환 함수를 구현하기 위해 인 람다에 대한 적절한 명령문이 필요하기 때문에 중요하다고 생각합니다. 예를 들면 :

std::vector<int> v{ 0, 1, 0, 2, 0 };
std::vector<int> u{ 1, 0, 1, 0, 1 };

perform(v.begin(), v.end(), u.begin(), [](auto& a, auto& b){ 
    std::tie(a, b) = std::minmax(a, b);    
}); 

//v would be == {0, 0, 0, 0, 0}
//u would be == {1, 1, 1, 2, 1}

찾은 한 가지 내가 해결책 은 복사본을 적용하기 위해 참조 한정자없이 명시 적으로를 구성하는을 구석으로입니다 .std::tuplestd::pair<const&, const&>

std::tie(a, b) = std::tuple<int, int>(std::minmax(a, b)); 

이러한 그러나 <int, int>중복성은 특히 auto& a, auto& b이전에 말했을 때 다소 으 .. 끔찍해 보입니다 .


이 할당을 수행하는 멋지고 짧은 방법이 있습니까? 이것이 잘못된 방향이고 단지 if (a >= b) { std::swap(a, b); }말하는 것이 최선의 접근 방식입니까?


이니셜 라이저 목록을 사용할 수 있습니다 minmax.

std::tie(a, b) = std::minmax({a, b});

이것은 단항 플러스를

사용할 때처럼 임시 object-가 생성되도록 하지만, 플러스 단항 연산자 가없는 유형에서도 작동한다는 이점이 있습니다.

using namespace std::string_view_literals;

auto [a, b] = std::make_pair("foo"sv, "bar"sv);
std::tie(a, b) = std::minmax({a, b});
std::cout << "a: " << a << ", b: " << b << '\n';

다수 :

a: bar, b: foo

이것이 잘못된 방향이고 단지 if (a >= b) { std::swap(a, b); }말하는 것이 최선의 접근 방식입니까?

나는 비교 요구 사항 if(b < a) std::swap(a, b);때문에 그것을 만들을 구석으로 입니다. 그러나 예, 당신이 생각하고 싶은 것이 여전히 매우 분명합니다.


[1] Compare [...] Compare를 만족하는 유형의 객체에 대한 함수 호출 연산의 반환 값은 상황에 따라 bool로 변환 할 때 호출의 첫 번째 인수가 strict weak에서 두 번째 인수보다 먼저 true를 반환합니다. 이 유형에 의해 유도 된 순서 관계, 즉 거짓.


다음과 같이 특정 수준의 간결함으로이를 시행 할 수 있습니다.

std::tie(a, b) = std::minmax(+a, +b);

std::cout << "a: " << a << ", b: " << b << '\n';

설명 : 내장 단항 더하기 연산자는 단항 빼기 형제와의 대칭을 위해 피연산자 를 값으로 반환 합니다 (일반적인 산술 변환도 수행하지만 ints 에는 적용되지 않음 ). 이는이 임시가 피연산자의 복사본 일지라도 임시를 만들어야 함을 의미합니다. 그러나이 minmax예제에서 사용하는 경우 충분합니다. 오른쪽의 참조 (에 const int&전달 인수 minmax)가 왼손의 참조와 동일한 객체를 참조하지 않기 때문에 여기서 참조를 교체해도 더 이상 할당되지 않습니다. 측면 (에서 tuple만든 참조의 내부 std::tie).

출력은 원하는대로입니다.

a : 5, b : 7


때로는 한 걸음 물러서서 다른 방법을 찾는 것이 효과가 있습니다.

if (b < a)
    std::iter_swap(&a, &b);

그것은 간결하고 일반적으로 더 효율적이며 적어도 동등합니다. 자체 기능으로 압축 할 수도 있습니다.

template <class T>
void reorder(T& a, T& b)
noexcept(noexcept(b < a, void(), std::iter_swap(&a, &b))) {
    if (b < a)
        std::iter_swap(&a, &b);
}

내가 사용하고 std::iter_swap()난 사용하지 않도록 using std::swap; swap(a, b)를 소개하는 사전 C ++ 2A에 일반성에 대한 두 단계를 정의 포인트가 객체 되지 않는 것을 만드는.

참조 URL : https://stackoverflow.com/questions/56739747/is-there-a-nice-way-to-assign-stdminmaxa-b-to-stdtiea-b

반응형