2016-07-15 6 views
3

가변 개수의 인자를 가진 제공된 함수를 호출하는 함수를 만들고 있습니다. Visual Studio 2015에서 올바르게 컴파일되고 작동하지만 Clang에서는 컴파일되지 않습니다. 나는 내가하려고하는 것을 보여주는 시위를 준비했다. 내가 연타 얻을 오류 : 모든 standard library algorithm function 보면, 적어도 사람이 "조건"(호출 가능한 객체)를 복용템플릿 매개 변수 팩은 Clang하지만 실패하지는 않습니다. VS 2015

prog.cpp: In function 'int main()': prog.cpp:31:2: error: no matching function for call to 'run(std::vector&, void ()(int&, const int&), const int&)' ); ^prog.cpp:7:6: note: candidate: template void run(std::vector&, const std::function&, mutrArgs ...) void run( ^prog.cpp:7:6: note: template argument deduction/substitution failed: prog.cpp:31:2: note: mismatched types 'const std::function' and 'void ()(int&, const int&)' );

#include <functional> 
#include <iostream> 
#include <vector> 
using namespace std; 

template<int RepeatTimes, class ... mutrArgs> 
void run(
    vector<int>& vec, 
    const function<void(int&, mutrArgs ...)>& mutr, 
    mutrArgs ... args 
) 
{ 
    for (int times{0} ; times < RepeatTimes ; ++times) 
     for (auto& item : vec) 
      mutr(item, args...); 
} 

void adder(int& i, const int& val) 
{ 
    i += val; 
} 

int main() 
{ 
    vector<int> v{0,1,2,3,4,5,6,7,8,9}; 
    const int addValue{4}; 
    run<2, const int&>(
     v, 
     &adder, 
     addValue 
    ); 
    for (auto i : v) 
     cout << i << " "; 
    cout << endl; 
    return 0; 
} 
+0

'std :: function' 대신에 모든 [표준 알고리즘 함수] (http://en.cppreference.com/w/cpp/algorithm)와 같이 형식을 템플릿으로 만드십시오. –

+0

비 데모 기능에서는 설정된 수의 인수를 취해야합니다. – JadziaMD

+2

'std :: function (& adder)'를 사용하면 컴파일됩니다. 왜 그것이 지정해야하는지 확실하지 않습니다. 짐작할 수없는 꾸러미 부분과 관련이 있을지 모르지만 규칙에 대해서는 확실하지 않습니다. – NathanOliver

답변

1

run<2, const int&> 단지 첫 번째 인수를 나타내지 만 공제는 비활성화하지 않습니다.

run<2, const int&>(v, &adder, addValue); 

mutrArgs 추론은 2 곳을 가지고

  • addValue ->mutrArgs = A std::function 때문에 실패 할 것이다 { const int& }

  • &adder.

함수의 주소가 그 문제

auto call_run = &run<2, const int&>; 
call_run(v, &adder, addValue); 

를 해결 촬영 이상하게도, 그 소리는 GCC에 인라인 사용 반대를 지원하지 않습니다/

(&run<2, const int&>)(v, &adder, addValue); 

당신이 공제를하지 않으려면, 당신은 당신의 템플렛 arg를 비 추론 할 수 없게 만들 수 있습니다 :

template <typename T> struct identity { using type = T; }; 

template <typename T> using non_deducible_t = typename identity<T>::type; 

그리고 귀하의 경우 요아킴 Pileborg에 의해 제안 같은 간단한 typename F 더 나은 것 같다하더라도

Demo

template<int RepeatTimes, class ... mutrArgs> 
void run(
    std::vector<int>& vec, 
    const std::function<void(int&, non_deducible_t<mutrArgs> ...)>& mutr, 
    non_deducible_t<mutrArgs> ... args 
) 
다음

.

+0

마지막으로 clang에서 올바르게 컴파일하려면 함수 주소를 얻고 추론 템플릿을 사용합니다. – JadziaMD

1

그들이 템플릿 유형으로 그 인수를.

이 같은 행동을 할 경우가 구축됩니다

template<int RepeatTimes, typename F, class ... mutrArgs> 
void run(
    vector<int>& vec, 
    F mutr, 
    mutrArgs ... args 
) 
{ 
    ... 
} 

here for an example of you code를 참조하십시오. 모든 템플릿 인수를 제공 할 필요는 없으므로 컴파일러가 템플릿 인수를 추론 할 수 있습니다.

+0

이것은 필요한 사용법을 우회하며 당연히 물론 작동합니다. – JadziaMD