2017-01-23 8 views
0

단항 및 이진 부정 자의 유용성은 쉽게 이해할 수 있습니다. 단항 부정 ( not1)와부정 부인 작성 방법?

예 :

class Even 
{ 
public: 
    bool operator() (const int& x) const { return x % 2 == 0; } 
    typedef int argument_type; 
}; 

int values[] = { 9, 1, 8, 2, 7, 3, 6, 4, 5 }; 

int even = count_if(values, values + 9, Even()); 
int odd = count_if(values, values + 9, not1(Even())); // <= unary negator 
cout << "We have " << even << " even elements in the array.\n"; 
cout << "We have " << odd << " odd elements in the array.\n"; 

출력 :

012,396,706,298,941,212,528,696,432 바이너리 부정 ( not2)와

We have 4 even elements in the array. 
We have 5 odd elements in the array. 

예 10

출력 :

9 1 8 2 7 3 6 4 5 
1 2 3 4 5 6 7 8 9 
9 8 7 6 5 4 3 2 1 

어떤 n 차 네게 이터 (not3, not4, not5 ... notn)에 대한?

이 아닌 요소의 수를 사이에 두 개의 수 (하한 한도 및 상한 한도)로 계산해야한다고 가정 해 봅시다.

. 

int elems_betweem = count_if(values, values + n, not3(bind(Between<int>(), _1, lowerValue, upperValue))); 

. 

은 어떻게 not3 부정을 작성하려면 어떻게해야합니까?

더욱, 우리는 bind1stbind2ndbind와 같은 방법으로 not1not2의 대용품으로 일반적인 not을해야합니까?

사용할 수 있습니다 C++ 17 std::not_fn 때문에 당신에게

+2

여기에 'not3'이 필요 없습니다. - bind ((), _1, lowerValue, upperValue 사이)는 단항 연산자를 생성하므로 간단히'not1'이 필요합니다. – Holt

+1

C++ 17은 어떤 상황에서도 작동 할 수있는'std :: not_fn'을 소개합니다. – user2079303

+0

예제에서는'not1'이 필요하고'not3'은 필요하지 않습니다. 'bind ((), _1, lowerValue, upperValue 사이)의 반환 값은 하나의 매개 변수를 취하고 3이 아닌 호출 가능한 호출입니다. –

답변

1

감사합니다

auto between = [](int value, int lowerValue, int upperValue) { 
    return lowerValue < value && value < upperValue; 
}; 

int elems_between = std::count_if(std::cbegin(values), std::cend(values), 
    std::bind(std::not_fn(between), std::placeholders::_1, lowerValue, upperValue)); 

wandbox example

+0

멋진! 당신은 질문에 대답하고 또한 C++의 차기 버전에서 작동 예제를 작성합니다. 매일 C++을 더 좋아합니다! 세상에. NET과 자바! – user7140484

0

은 어떻게 not3의 부정을 작성하려면 어떻게해야합니까?

C++ 03을 준수 예 :

template<class Pred> 
class ternary_predicate { 
    Pred pred; 
public: 
    ternary_predicate(Pred pred): pred(pred){} 

    template<class A, class B, class C> 
    bool 
    operator()(A const& a, B const& b, C const& c) const { 
     return !pred(a, b, c); 
    } 
}; 

template<class Pred> 
ternary_predicate<Pred> 
not3(Pred pred) { 
    return ternary_predicate<Pred>(pred); 
} 

이 더욱, 우리는 bind1st 및 bind2nd 대 바인드와 같은 방법으로 not1 및 not2의 대용품으로 일반적인하지가 있나요?

일단 C++ 17이 공식적으로 사용됩니다. std::not1std::not2 대신에 std::not_fn을 도입하면 더 이상 사용되지 않습니다.당신이 참을성이 느끼는 경우

, 자신에 구현하기 어려울 안있어 C++ 14 :

template<class Pred> 
auto 
not_fn(Pred&& pred) { 
    return [pred=std::forward<Pred>(pred)](auto&&... args){ 
     return !pred(std::forward<decltype(args)>(args)...); 
    }; 
} 
0

당신은 쓸 수 있습니다 자신의 std::not_fn 한이 사용할 수없는 같이

template <typename T> 
struct not_func 
{ 
    template <typename...Args> 
    constexpr bool operator()(const Args&...args) const { return !T{}(args...); } 
}; 

사용 예제 :

int main() 
{ 

    bool a1 = std::less<int>{}(1, 2); 
    bool a2 = not_func<std::less<int>>{}(1, 2); 

    bool b1 = Even{}(1); 
    bool b2 = not_func<Even>{}(1); 


    std::cout 
     << "a1 = " << (a1 ? "true" : "false") << "\n" 
     << "a2 = " << (a2 ? "true" : "false") << "\n" 
     << "b1 = " << (b1 ? "true" : "false") << "\n" 
     << "b2 = " << (b2 ? "true" : "false") << "\n"; 
} 

[On Coliru],[On Godbolt]

가능한 모든 변형을 테스트하지 않았으므로 여전히 버그가있을 수 있습니다.