2014-02-11 11 views
1

현재 VS 2013을 사용하는 Windows에서 컴파일되지 않는 라이브러리 (entityx)를 수정하려고합니다. gcc가있는 Linux 및 MinGW가있는 Windows에서도 잘 컴파일됩니다.VS 2013 SFINAE 결함에 대한 해결 방법

SFINAE에 문제가있는 것으로 보입니다. VS 2013이 템플릿 대체 오류를 제대로 무시하지 못하는 것 같습니다.

Microsoft Connect에서이 문제에 대한보고가 있습니다 (here).

:

#include <vector> 
#include <future> 

using namespace std; 

typedef int async_io_op; 

struct Foo 
{ 
    //! Invoke the specified callable when the supplied operation completes 
    template<class R> inline std::pair < std::vector < future <R>> , std::vector <async_io_op>> call(const std::vector<async_io_op> &ops, const std::vector < std::function < R() >> &callables); 
    //! Invoke the specified callable when the supplied operation completes 
    template<class R> std::pair < std::vector < future <R>> , std::vector <async_io_op>> call(const std::vector < std::function < R() >> &callables) { return call(std::vector<async_io_op>(), callables); } 
    //! Invoke the specified callable when the supplied operation completes 
    template<class R> inline std::pair<future<R>, async_io_op> call(const async_io_op &req, std::function<R()> callback); 
    //! Invoke the specified callable when the supplied operation completes 
    template<class C, class... Args> inline std::pair<future<typename std::result_of<C(Args...)>::type>, async_io_op> call(const async_io_op &req, C callback, Args... args); 
}; 

int main(void) 
{ 
    Foo foo; 
    std::vector<async_io_op> ops; 
    std::vector < std::function < int() >> callables; 
    foo.call(ops, std::move(callables)); 
    return 0; 
} 

내가이 컴파일하려고 다음과 같은 오류가 발생합니다 :

내가 entityx로 다이빙을하기 전에

은 (연결 Microsoft의 보고서에서 가져온) 문제의 샘플이

오류 C2064 : 용어가 0 인수를 취하는 함수로 평가되지 않습니다.

c : \ program files (x86) \ microsoft visual studio 12.0 \ vc \ include \ xrefwrap 58

분명히이 문제를 해결하기 위해 std::enable_if을 사용할 수 있습니다. 그러나, 나는 방법을 이해할 수 없다.

누구든지이 컴파일 오류를 해결할 수있는 방법을 알고 있습니까?

편집 : 전체 출력 VS 2013 : 당신이 decltype + std::declval 동등한와 std::result_of를 교체 할 경우

1>------ Build started: Project: VS2013_SFINAE_Failure, Configuration: Debug Win32 ------ 
1> test_case.cpp 
1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\xrefwrap(58): error C2064: term does not evaluate to a function taking 0 arguments 
1>   c:\program files (x86)\microsoft visual studio 12.0\vc\include\xrefwrap(118) : see reference to class template instantiation 'std::_Result_of<_Fty,>' being compiled 
1>   with 
1>   [ 
1>    _Fty=std::vector<std::function<int (void)>,std::allocator<std::function<int (void)>>> 
1>   ] 
1>   c:\users\jarrett\downloads\vs2013_sfinae_failure\vs2013_sfinae_failure\test_case.cpp(25) : see reference to class template instantiation 'std::result_of<std::vector<std::function<int (void)>,std::allocator<_Ty>> (void)>' being compiled 
1>   with 
1>   [ 
1>    _Ty=std::function<int (void)> 
1>   ] 
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ========== 
+1

나는 이런 식으로 일한 것을 기억합니다. 많은 스트레스 공과 조직이 있기를 바랍니다. –

+0

전체 오류를 게시 할 수 있습니까? 후속 행은 일반적으로 추가 정보를 제공합니다. –

+0

@ R.MartinhoFernandes 완료. – Jarrett

답변

3

VS2013 코드를 컴파일합니다. 내가 here을 설명 올바르게,이 결함에 관련이 오류를 이해한다면 그래서

template<class C, class... Args> 
inline pair<future<decltype(declval<C>()(declval<Args>()...))>, async_io_op> 
call(const async_io_op& req, C callback, Args... args); 

에 마지막 Foo::call() 정의를 변경할 수 있지만 그것은 모두 GCC와 그 소리가 오류없이 result_of 코드를 컴파일 관리하는 것은 놀라운 일이다.

+0

@Praetorian 답장을 보내 주셔서 감사합니다. 복사 및 붙여 넣기를 시도했지만 대신 '오류 LNK2019 : 확인할 수없는 외부 기호'오류가 표시됩니다. – Jarrett

+0

@Jarrett 글쎄, gcc와 clang을 사용하면 main에서 호출하려고하는'Foo :: call'이 정의되지 않았기 때문에 이것을 얻을 수있다. – Praetorian

+0

Oh haha. 좋아 그럼 내가 해결할 것 같아 :) 고맙습니다 @ 프리토리아. – Jarrett