2017-11-18 5 views
0

컴파일러에서 다음 오류가 발생합니다. error: no match for 'operator+' (operand types are 'Expected<double>' and 'Expected<double>') 예상되거나 형식입니다.동일한 유형의 두 템플릿에 대한 작업을 올바르게 수행하는 방법은 무엇입니까?

template<typename T> 
class Expected 
{ 
    template<typename U> 
    Expected<U> apply(std::function<U(T)> f) 
    { 
     if(!valid) return std::get<std::exception_ptr>(state); 
     try 
     { 
      return f(std::get<T>(state)); 
     } 
     catch(...) 
     { 
      return std::current_exception(); 
     } 
    } 
}; 


#define MixedMode(op)\ 
template<typename T, typename U, typename V>\ 
Expected<U> op(Expected<T> t, Expected<V> v)\ 
{\ 
    return t.apply([&](T myT){return op(v,myT);});\ 
}\ 
template<typename T, typename U, typename V>\ 
Expected<U> op(Expected<T> t, V v)\ 
{\ 
    return t.apply([&](T myT){return op(myT,v);});\ 
}\ 
\ 
template<typename T, typename U, typename V>\ 
Expected<U> op(V v, Expected<T> t)\ 
{\ 
    return t.apply([&](T myT){return op(v,myT);});\ 
}\ 


MixedMode(operator+) 

int main() 
{ 
    Expected<double> a; 
    Expected<double> b; 

    a + b; 
} 

저는 헤더 파일에 과부하를 걸고 함께 추가 할 수 있다고 생각합니다. 처음에는 두 개의 템플릿을 함께 추가 할 것을 기대하고 있습니다. 내 주 파일에서 간단히 다음을 호출합니다.

Expected<double> a; 
Expected<double> b; 
std::cout << a + b << std::endl; 

그런 다음 오류가 발생합니다. 코드의 Expected<U> op(Expected<T> t, Expected<V> v)\ 부분을 추가하기 전에 operator T() { return value(); }이라는 함수가 있었는데 Expected<T>을 전달 된 형식으로 암시 적으로 캐스팅하는 경우 컴파일하고 실행할 수있었습니다. 그러나 apply 함수가 사용 된 적이 없다는 것을 깨달았습니다. 뿐만 아니라, a+b의 유형을 확인했을 때 대신 double이 반환되었으므로 operator T() 함수가 제거되었고 컴파일러가 두 개의 Expected<T>을 함께 추가하는 방법을 알 수 없다고 알려주었습니다.

어떻게이 오류를 수정합니까? 나는 하루 종일 머리를 때리고있다.

+1

[mcve]로 이길 수 있습니까? 예를 들어 매크로가 없으면 작동하지 않을 것이므로 클래스 내부에 모든 왕겨가 필요하지는 않습니다. 아마 [이걸 쓰러 뜨리면] (https://ideone.com/cNcRpF) 여전히 같은 오류가 발생할 수 있습니다. 왜 여분의 소음으로 실험 해보아야합니까? – user4581301

+0

@ user4581301 필자는 최소한의 예제로이 연산자를 배제하려고 시도 할 수있다. operator <<를 제외하고는 필자가 필요로한다는 것을 알았으므로 아무도 스스로 작성하지 않아도된다. 너를 사용할 수 있을까? – Sailanarmo

+0

@ user4581301'+ =, - =, ='등의 연산자를 제외한 모든 연산자를 사용하기 때문에 매크로가 생겼습니다. 그래서 지금은 그대로 두어야한다고 생각했습니다. – Sailanarmo

답변

0

템플릿 함수 본문은 템플릿 매개 변수를 추론하는 데 사용되지 않습니다. U은 인수에서 추론 할 수 없으므로 + 오버로드가 무시됩니다.

#define MixedMode(op)\ 
template<typename T, typename V>\ 
auto op(Expected<T> t, Expected<V> v)\ 
{\ 
    return t.apply([&](T myT){return op(v,myT);});\ 
}\ 
template<typename T, typename V>\ 
auto op(Expected<T> t, V v)\ 
{\ 
    return t.apply([&](T myT){return op(myT,v);});\ 
}\ 
template<typename T, typename V>\ 
auto op(V v, Expected<T> t)\ 
{\ 
    return t.apply([&](T myT){return op(v,myT);});\ 
} 

이것은 컴파일에 실패하지만, 이는 사용자가 apply을 잘못 작성했기 때문입니다.

std::function은 람다가 아니며 람다는 std::function이 아닙니다. std::function 999/1000 회 유형을 추론 할 경우, std::function은 지우기 유형에 대한 공제이며, 유형 공제에 대한 공제는 이며 그 반대 개념은입니다.

더 중요하게, 당신은 그들을 뒤에서 구성하고 있으며, 그런 식으로 구성하지 않습니다.

template<class F> 
Expected<std::invoke_result_t<F&,T&>> apply(F f){ 

또는 이와 유사한 것.

+0

죄송합니다. 언젠가는 내 머리를 감싸고 있습니다. 그러나 나는 아직도 적용이 잘못 쓰여진 것인지 잘 모르겠습니다. 결과가 예외가 아니면 'Expected + Expected '이라고 가정하는 작업을 수행하고 결과를 반환하십시오. 어떤 것이 있으면 예외를 잡아라. 나는 또한'std :: invoke_result_t'를 본 적이 없다. 어떻게 작동하는지 설명해 주시겠습니까? 그리고 마지막으로, apply가 올바르게 수행되면 나머지 컴파일러 에러는 사라지게 될까요? – Sailanarmo

+0

나는 정정 된 코드를 주었다. 그것에 대해 불분명 한 점은 무엇입니까? 신청서를 제출했습니다. 나는 어떤 오류라도 찾아 낼 수 있었다. 귀하의 질문에 [mcve]가 없으므로 다른 오류가 있는지 모르거나 온라인 컴파일러에서 코드를 테스트 한 결과 오타가 발생할 수 있습니다. googling'std :: invoke_result'를 시도하고 [this site] (http://en.cppreference.com/w/cpp/types/result_of)라고 읽었습니까? 그것에 대해 읽은 후에 새로운 질문이있는 경우 "질문하기"버튼을 클릭하거나 SO를 검색하면 좋은 계획입니다. 의견이 너무 짧습니다. – Yakk