2012-11-06 3 views
18

바인드에서 반환 된 객체가 추가 인수를 무시하는 이유는 무엇입니까?

void f(int x, int y); 

, 나는 두 개의 인자를받는 함수가 있다고 가정하고 나는 그들 중 하나를 바인딩합니다. 다음과 같이 나는 std::bind를 사용할 수 있습니다

auto partiallyBoundF = std::bind(f, 10, _1); 

partiallyBoundF는 하나의 인자를,하지만 난 더 이상 그것을 호출 할 수 있습니다.

partiallyBoundF(20, 0); 
partiallyBoundF(0, 44, -99, "Hello", 4.5, true, []{}); 

추가 인수를 전달하기 위해 허용 개체의 목적은 bind에서 반환 무엇 : 첫 번째 넘어 인수는 심지어 어떤 의미가있는 종류 일 필요 없다? 호출 오류를 컴파일하여 다른 곳에서는 거부 될 수 있습니다.

+3

어떤 컴파일러입니까? 나는 이것이 부적합한 컴파일러일지도 모른다는 것을 추측 할 수있다. 왜냐하면 그러한 추가적인 인수를 허용하는 것은 실제로는 의미가 없기 때문이다. 예를 들어, MSVC는 가변적 인 템플릿을 에뮬레이션합니다. 각 템플릿은 가능한 최대 템플릿 인수를 취하고 기본값을 일부 NIL 유형으로 기본 설정합니다. 어쩌면 그게 뭔가 행동의 원인일까요? –

+3

@ChristianRau : 표준의 일부입니다. 그것은 TR1의 일부이기도합니다. 20.8.2/4는 variadic-templatized'operator()'에 대한 예상 된 구현이 인수의 유형이나 수에 관계없이 전달 된 것을 취하도록 주석을 작성합니다. TR1도 비슷한 문구를 가지고 있습니다. – KnowItAllWannabe

+1

당신의 경우,'N = sizeof ... (bound_args)'(호출을 바인딩하는 args의 수)는 유효한 표현식이어야한다. 20.8.9.1.2/2를 보아라. 20.8.2/1. 편집 : 그것은 그것을 호출하는 다른 방법을 허용하지 않습니다. – dyp

답변

16

추가 인수를 무시하면 훨씬 간단하게 구현할 수 있으며 실제로 유용 할 수 있습니다.

예를 들어, libstdC++ (g ++) 접근법은 튜플에 operator() 인수를 수집 한 다음 std::placeholder 바인드 인수를 필요에 따라 추출하도록합니다. 인수 카운트를 적용하려면 사용 된 자리 표시 자의 수를 계산해야하는데 이는 꽤 복잡합니다. 바인드 호출 객체는 복수 또는 템플릿 화 된 operator() 호출 패턴을 가진 펑터가 될 수 있으므로 바인드 객체 operator()은 "올바른"단일 서명으로 생성 될 수 없습니다.

또한 당신이 쓸 수 있습니다 :

std::bind(&foo, std::placeholders::_1, std::placeholders::_3); 

즉 명시 적으로 바인딩 개체에 두 번째 인수를 무시. bind이 인수 카운트를 실시하면 추가 지정 방법이 필요합니다. 네 번째 주장도 무시되었다. 유용성에 대해서는

는 신호에 부재 신호 처리기 결합 고려해 sig 후들은 단순히 bind 물체가 무시되는 추가 불필요한 발광 파라미터를 갖는다

sig.connect(std::bind(&C::on_sig, this, param, std::placeholders::_1)); 

경우; 그렇지 않으면 동일한 신호 처리기를 여러 신호에 바인딩하려면 실제 용도가 아닌 여러 전달 래퍼를 작성해야합니다.

+3

"더 유용합니다"- 나는 그것을 논할 것입니다. 이것은 강한 타이핑을 해친다. 그리고 원한다면이 동작은 가변 인수를 받아들이는 프록시 펑터를 사용하는 것만으로도 엄격한'std :: bind'로 에뮬레이트 될 수 있습니다. –

+2

@KonradRudolph 호출 가능 객체가 여러개의'operator()'를 가진 펑터 인 경우 바인드 표현식은 일반적인 경우에 잘 정의 된 타입을 가지지 않습니다. – ecatmur

+0

람다를 사용하여 네 번째 인수를 무시할 수 있습니다. 그래도별로 좋지는 않습니다. – dyp