2015-12-11 16 views
6

Więc powiedzmy, że mam ten kod:Jak przekazywać elementy wektorowe jako argumenty do funkcji szablonu variadic?

template <class T1, class T2> 
auto sum(T1 a, T2 b) ->decltype(a + b) { 
    return a + b; 
} 
template <class T1, class T2, class... T3> 
auto sum(T1 a, T2 b, T3... tail) ->decltype(a + sum(b, tail...)) { 
    return a + sum(b, tail...); 
} 

chciałbym funkcję sum nazwać w sposób mijam Vector:

vector<double> numbers = { 1, 2, 6, 5 }; 

, które powinny być wykorzystywane jako lista argumentów za funkcja sum. Jak mogę to zrobić? Funkcja wywołania sum powinna w takim przypadku powrócić do numeru 14.

+1

Funkcje varariadic są rozwiązywane w czasie kompilacji, a wektory mają określony rozmiar środowiska wykonawczego. Być może powinieneś zamiast tego specjalizować się na argumenty wektorowe. – jaggedSpire

+1

Możesz również użyć std :: array, którego rozmiar jest znany podczas kompilacji. – Brian

+0

@ Claudiu tylko FYI: twoje punkty odsyłaczy tutaj. ;-) – jaggedSpire

Odpowiedz

9

std::vector to bestia prowadzona w czasie rzeczywistym. Oznacza to, że alokuje swój bufor na stercie i ogólnie dowolna manipulacja jest dozwolona podczas wykonywania. Z drugiej strony szablon variadic "pealing" jest wykonywany podczas kompilacji. W związku z tym szablonyi variadic są nieco "rozłączne". W związku z tym nie jest możliwe robienie tego, co chcesz, za pomocą wektora.

Jeśli chcesz zsumować elementy wektora Można to zrobić w czasie wykonywania przy użyciu std::accumulate:

std::vector<int> v{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 
int sum = std::accumulate(v.begin(), v.end(), 0); 

Jak Brian wspomniano w komentarzach można użyć std::array dla kompilacji obliczania czasu w połączeniu z constexpr funkcji. Przykładem, jak można to zrobić jest wyświetlany poniżej:

namespace detail { 
template <class T1, class T2> 
constexpr auto sum_(T1 a, T2 b) { 
    return a + b; 
} 
template <class T1, class T2, class... T3> 
constexpr auto sum_(T1 a, T2 b, T3... tail) { 
    return a + sum_(b, tail...); 
} 

template <typename T, std::size_t N, std::size_t... Is> 
constexpr T sum_impl(std::array<T, N> const &src, std::index_sequence<Is...>) { 
    return sum_(src[Is]...); 
} 

} 

template <typename T, std::size_t N> 
constexpr T sum(std::array<T, N> const &arr) { 
    return detail::sum_impl(arr, std::make_index_sequence<N>{}); 
} 

Live Demo

W powyższym przykładzie I oznaczonej swoje sum funkcje constexpr. Możesz również dowiedzieć się, w jaki sposób możesz użyć std::make_index_sequence, aby podać elementy swojej tablicy jako argumenty do swojej funkcji variadic sum.

Powiązane problemy