Я хочу 4 перегрузки функции шаблона.Функция принимает диапазон значений y и другой диапазон значений x.Эти диапазоны могут быть указаны как итераторы или как контейнеры.Если они передаются как контейнеры, функции итератора для контейнера вызываются с помощью begin
/ end
.Для xa существует особый случай, когда прохождение скаляра x будет обрабатываться так, как если бы все x в диапазоне [начало, конец) были этим значением.
#include <iterator>
#include <vector>
// 1) Take iterator [begin, end) for y values and scalar for x
template <typename Iterator>
std::vector<double>
func(Iterator ybegin, Iterator yend, typename Iterator::value_type x = 1.) {}
// 2) take sequence of y values and scalar for x
template <typename Sequence>
std::vector<typename Sequence::value_type>
func(const Sequence& y, typename Sequence::value_type x = 1.) {
return func(y.begin(), y.end(), x);
}
// 3) take iterator [begin, end) for y values and iterator [begin, end) for x values
template <typename Iterator1, typename Iterator2>
std::vector<double>
func(Iterator1 ybegin, Iterator1 yend, Iterator2 xbegin, Iterator2 xend) {}
// 4) take sequence of y values and sequence of x values
template <typename Sequence1, typename Sequence2>
std::vector<double>
func(const Sequence1& y, const Sequence2& x) {
return func(y.begin(), y.end(), x.begin(), x.end());
}
int main() {
std::vector<double> a{4, 5, 6};
std::vector<int> b{1, 1, 1};
func(a.begin(), a.end(), 0.2);
func(a.begin(), a.end(), b.begin(), b.end());
func(a, 0.2);
func(a, b);
}
Код, который я разместил выше, не компилируется, потому чтовызов с std::vector
и double
подходит для функции 2) (правильно) и 4) (неправильно).
error: call of overloaded ‘func(std::vector<double>&, double)’ is ambiguous
func(a, 0.2);
^
scratch_1.cpp:33:44: note: candidate: ‘std::vector<typename Sequence::value_type> func(const Sequence&, typename Sequence::value_type) [with Sequence = std::vector<double>; typename Sequence::value_type = double]’
std::vector<typename Sequence::value_type> func(const Sequence& y,
^~~~
scratch_1.cpp:50:21: note: candidate: ‘std::vector<double> func(const Sequence1&, const Sequence2&) [with Sequence1 = std::vector<double>; Sequence2 = double]’
std::vector<double> func(const Sequence1& y, const Sequence2& x) {
Если я использую следующие версии 2) и 4), я получаю
// 2)
template <typename Sequence>
std::vector<typename Sequence::value_type>
func(const Sequence& y, typename std::enable_if<std::is_scalar<typename Sequence::value_type>::value,
typename Sequence::value_type>::type x = 1.) {
return func(y.begin(), y.end(), x);
}
// 4)
template <typename Sequence1, typename Sequence2>
std::vector<double>
func(const Sequence1& y,
const typename std::enable_if<!std::is_scalar<Sequence2>::value, Sequence2>::type& x) {
return func(y.begin(), y.end(), x.begin(), x.end());
}
error: no matching function for call to ‘func(std::vector<double>&, std::vector<int>&)’
, поскольку тип второго вектора не может быть выведен.
error: no matching function for call to ‘func(std::vector<double>&, std::vector<int>&)’
func(a, b);
candidate: ‘template<class Sequence1, class Sequence2> std::vector<double> func(const Sequence1&, const typename std::enable_if<(! std::is_scalar<Sequence2>::value), Sequence2>::type&)’
std::vector<double> func(const Sequence1& y, const typename
^~~~
note: template argument deduction/substitution failed:
note: couldn't deduce template parameter ‘Sequence2’ func(a, b);