2013-11-23 2 views
1

내가이상한 오류가 때 가변 인자 템플릿

f([](int x, int y) {return x+y;}, {1, 2}); \\returns 3 
같은 기능과 벡터를 취하고 벡터에서 인수로 함수를 적용 기능, 뭔가를 만들려고을 사용하여 함수에 벡터에서 인수를 적용

내 현재 코드는 다음과 같습니다

#include <iostream> 
#include <vector> 
#include <functional> 
#include <type_traits> 
#include <boost/type_traits.hpp> 

template <std::size_t... Indices> 
    struct indices { 
    using next = indices<Indices..., sizeof...(Indices)>; 
}; 
template <std::size_t N> 
struct build_indices { 
    using type = typename build_indices<N-1>::type::next; 
}; 
template <> 
struct build_indices<0> { 
    using type = indices<>; 
}; 
template <std::size_t N> 
using BuildIndices = typename build_indices<N>::type; 

template <size_t num_args> 
struct unpack_caller 
{ 
private: 
    template <typename FuncType, size_t... I> 
    typename std::result_of<FuncType>::type call(FuncType &f, std::vector<int> &args,  indices<I...>){ 
     return f(args[I]...); 
    } 

public: 
    template <typename FuncType> 
    typename std::result_of<FuncType>::type operator() (FuncType &f, std::vector<int>  &args) 
    { 
     return call(f, args, BuildIndices<num_args>{}); 
    } 
}; 

template<typename InnerType, typename ...Args> 
class MFA 
{ 
    std::function<InnerType(Args...)> func; 
public: 
    MFA(InnerType f(Args...)) 
     : func(f) 
    {} 

    virtual InnerType calc(std::vector<InnerType> & x) 
    { 
     return unpack_caller<sizeof...(Args)>()(func, x); 
    } 
}; 


int main() 
{ 
    auto fun1 = MFA<int, int, int>([](int x, int y) {return x + y; }); 
    std::vector<int> arg = std::vector<int>({1, 2}); 
    fun1.calc(arg); 

    return 0; 
} 

을하고 오류를 제공합니다 (GCC 4.8.1) :

$g++ -std=c++0x main.cpp -o demo -lm -pthread -lgmpxx -lgmp -lreadline 2>&1 
main.cpp: In instantiation of 'InnerType MFA<InnerType,  Args>::calc(std::vector<InnerType>&) [with InnerType = int; Args = {int, int}]': 
main.cpp:68:18: required from here 
main.cpp:57:50: error: no match for call to '(unpack_caller<2ul>)  (std::function<int(int, int)>&, std::vector<int>&)' 
return unpack_caller<sizeof...(Args)>()(func, x); 
^ 
main.cpp:25:8: note: candidate is: 
struct unpack_caller 
^ 
main.cpp:35:45: note: template<class FuncType> typename std::result_of<FuncType>::type  unpack_caller<num_args>::operator()(FuncType&, std::vector<int>&) [with FuncType =  FuncType; long unsigned int num_args = 2ul] 
typename std::result_of<FuncType>::type operator() (FuncType &f, std::vector<int>  &args) 
^ 
main.cpp:35:45: note: template argument deduction/substitution failed: 
main.cpp: In substitution of 'template<class FuncType> typename  std::result_of<FuncType>::type unpack_caller<num_args>::operator()(FuncType&,  std::vector<int>&) [with FuncType = FuncType; long unsigned int num_args = 2ul] [with  FuncType = std::function<int(int, int)>]': 
main.cpp:57:50: required from 'InnerType MFA<InnerType,  Args>::calc(std::vector<InnerType>&) [with InnerType = int; Args = {int, int}]' 
main.cpp:68:18: required from here 
main.cpp:35:45: error: invalid use of incomplete type 'class  std::result_of<std::function<int(int, int)> >' 
In file included from /usr/local/gcc-4.8.1/include/c++/4.8.1/bits/move.h:57:0, 
from /usr/local/gcc-4.8.1/include/c++/4.8.1/bits/stl_pair.h:59, 
from /usr/local/gcc-4.8.1/include/c++/4.8.1/bits/stl_algobase.h:64, 
from /usr/local/gcc-4.8.1/include/c++/4.8.1/bits/char_traits.h:39, 
from /usr/local/gcc-4.8.1/include/c++/4.8.1/ios:40, 
from /usr/local/gcc-4.8.1/include/c++/4.8.1/ostream:38, 
from /usr/local/gcc-4.8.1/include/c++/4.8.1/iostream:39, 
from main.cpp:1: 
/usr/local/gcc-4.8.1/include/c++/4.8.1/type_traits:1878:11: error: declaration of  'class std::result_of<std::function<int(int, int)> >' 
class result_of; 

어떻게 수정할 수 있습니까? MFA::calc 함수는 MFA가 인터페이스 구현으로 간주되기 때문에 현재 가지고있는 유형을 가져야합니다.

편집 : 나는 유래 다음 질문에서 코드를 사용하고 : Any Solution to Unpack a Vector to Function Arguments in C++? Initialize std::array with a range (pair of iterators)

+0

왜 'std :: accumulate'가 아닌가요? – Adam

+0

첫 번째 인수가 * 원하는 모든 함수가되기를 원하기 때문에 (적절한 서명이있는 한) : –

답변

1

당신은 std::result_of<FuncType>::type을 사용할 수 없습니다, 당신은 인수, 예를 추가해야 std::result_of<FuncType(int,int)>::type. 귀하의 경우에는,이 더 어려운 대안보다, 따라서 나는 당신이 사용하는 것이 좋습니다 :

template <size_t num_args> 
struct unpack_caller 
{ 
private: 
    template <typename FuncType, size_t... I> 
    auto call(FuncType &f, std::vector<int> &args, indices<I...>) 
     -> decltype(f(args[I]...)) 
    { 
     return f(args[I]...); 
    } 

public: 
    template <typename FuncType> 
    auto operator() (FuncType &f, std::vector<int> &args) 
     -> decltype(std::declval<unpack_caller<num_args>>().call(f, args, BuildIndices<num_args>{})) 
    { 
     return call(f, args, BuildIndices<num_args>{}); 
    } 
}; 

Live example

참고 C++ (14), 당신은 -> decltype(...) 부분을 떠나 단순히 의존 수 auto.

+0

감사합니다 - 매력과 같이 작동합니다 :). 내가 예상했던 것보다 조금 더 복잡했다. –