2015-12-11 24 views
6

Vì vậy, chúng ta hãy nói rằng tôi có mã này:Làm cách nào để truyền các phần tử vectơ làm đối số cho hàm mẫu 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...); 
} 

Tôi muốn gọi hàm sum một cách tôi vượt qua một vector:

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

nên được sử dụng như một danh sách các đối số cho chức năng sum. Làm thế nào tôi có thể làm điều đó? Chức năng gọi sum phải trả lại 14 trong trường hợp này.

+1

Chức năng biến thể được giải quyết tại thời gian biên dịch và các vectơ có kích thước xác định thời gian chạy. Có lẽ bạn nên chuyên cho các đối số vector, thay vào đó. – jaggedSpire

+1

Bạn cũng có thể sử dụng std :: array, có kích thước được biết tại thời gian biên dịch. – Brian

+0

@Claudiu chỉ là một FYI: liên kết của bạn chỉ ở đây. ;-) – jaggedSpire

Trả lời

9

std::vector là một con thú thời gian chạy. Nghĩa là, nó phân bổ bộ đệm của nó trên heap và thường bất kỳ thao tác nào được cho phép trong thời gian chạy. Mặt khác, mẫu variadic "pealing" được thực hiện trong suốt thời gian biên dịch. Do đó, một mẫu std::vector và variadic có phần "rời rạc". Vì vậy, bạn không thể làm những gì bạn muốn với một vectơ.

Nếu bạn muốn tổng hợp các yếu tố của một véc tơ này có thể được thực hiện trong thời gian chạy bằng 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); 

Như Brian đề cập trong các ý kiến ​​bạn có thể sử dụng một std::array cho tính toán thời gian biên dịch kết hợp với constexpr chức năng. Một ví dụ về cách bạn có thể làm điều này được hiển thị dưới đây:

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

Trong ví dụ trên tôi đánh dấu sum chức năng của bạn constexpr. Bạn cũng có thể tìm ra cách bạn có thể sử dụng std::make_index_sequence để nạp các phần tử của mảng làm đối số cho hàm variadic sum của bạn.

Các vấn đề liên quan