2017-12-29 23 views
0

std::visit과 함께 std::bind을 사용하여 방문자가 연결된 기능을 얻으려고합니다.std :: bind를 std :: visit과 함께 사용하기

"오버로드 된 함수의 인스턴스가 없습니다."하지만 바인딩에 관해 내가 뭘 잘못하고 있는지 전혀 알지 못합니다.

std::bind을 방문자를 캡처하는 방법은 무엇입니까?

#include <variant> 
#include <functional> 
#include <iostream> 

using Somenum = std::variant<uint64_t, double>; 

struct Visitor { 
    uint64_t operator()(const uint64_t& num) const { 
     return num; 
    } 
    uint64_t operator()(const double& num) const{ 
     return 5; 
    } 
}; 

int main(int argc, char **argv) { 
    const Somenum a = 3.0; 
    const Somenum b = (uint64_t)6; 
    const Visitor v{}; 
    const auto f = std::bind(std::visit<Visitor, Somenum>, v, std::placeholders::_1); 
    const auto f2 = [&v](Somenum x) { 
     return std::visit(v, x); 
    }; 

    std::cout << f(a) << std::endl << f(b)<< std::endl; 

    std::cout << f2(a) << std::endl << f2(b) << std::endl; 
    return 0; 
} 

효과적으로 나도 같은 행동

f이 모든 컴파일 할 수라고 선을 제거를 가지고 ff2을하고 싶습니다.

+0

값을 얻기 위해'std :: get (s)'을 할 필요가 없습니다. 변형이 해당 유형을 보유하고 있는지 확인하려면 아마도'std :: holds_alternative (s)'을 (를) 사용 하시겠습니까? 마찬가지로 '이중'. – Eljay

+0

그렇게 생각하지 마십시오. 어디에서해야합니까? std :: visit은 내가 생각하는대로 처리해야합니다. – Bomaz

+0

왜 람다 대신에'std :: bind'를 사용하고 싶습니까? C++ 1z의 최신 핫스팟과 언어의 람다 (lambdas)에 대한 필요성을 보여준 clunky old stuff를 혼합했습니다. – metal

답변

4

<unresolved overloaded function type> 오류를 설명 할 수 없지만 어쨌든 잘못되었습니다. std::visit는 전달 참조의 무리를한다, 그래서 std::visit<Visitor, Somenum>는 유형이 같은 것입니다 함수 포인터입니다 :

decltype(auto)(*)(Visitor&&, Somenum&&); 

사람들은를 rvalue 참조입니다. 하지만 실제로 rvalues로이 함수를 호출하지는 않습니다. lvalues로 호출합니다. const lvalues도. 따라서 원하는 버전은 실제로 std::visit<Visitor const&, Somenum const&>입니다. 이 작품 :

auto p = std::visit<Visitor const&, Somenum const&>; 
const auto f = std::bind(p, v, std::placeholders::_1); 

다시 나는 당신이 p를 미리 선언 할 필요 이유를 모르겠어요.


이렇게하면 람다를 사용하는 것이 왜 더 나은지 분명히 알 수 있습니다. 올바른 템플릿을 얻기 위해 수동으로 인수를 공제하지 않아도됩니다!