GCD нескольких параметров

Моей целью было обобщить __gcd() доступно в стандарте <algorithm> заголовок в C ++. который должен быть в состоянии вызвать диапазон значений std::vector массив.

Обобщенный шаблон __gcd() отлично работает, когда параметры были переданы напрямую. Как показано ниже:

math::GCD(1,2,58,54);

Однако, когда я попытался передать диапазон значений вектора (код приведен ниже), он показывает следующую ошибку:

D:\Programming\C++\CPP Programs\My Test\My Test.cpp|33|error: no match for 'operator<<' (operand types are 'std::ostream {aka std::basic_ostream<char>}' and '__gnu_cxx::__normal_iterator<int*, std::vector<int> >')|

Я не знаю как перегрузить operator<< или включите функцию перегрузки в этот шаблон / программу. (при условии, что ошибка вызвана перегрузкой operator<< пропустил)

namespace math
{

template <typename M, typename N>
constexpr auto GCD(const M& m, const N& n) {
return __gcd(m, n);
}

template <typename M, typename ...Rest>
constexpr auto GCD(const M& first, const Rest&... rest) {
return __gcd(first, GCD(rest...));
}
}

int main()
{
vector<int> vec={1,2,58,54,102,2,37,13,8};
for(auto i=0; i<vec.size()-3; ++i)
cout<<math::GCD(vec.begin()+i, vec.begin()+i+4)<<endl;
return 0;
}

кто-нибудь может помочь мне перегрузить operator<< или (если это не так) найти ошибку?
заранее спасибо.

0

Решение

Я сделал это наконец. Спасибо за последний комментарий @Incomputable. Тем не менее, я должен был сделать разделение между новым шаблоном (для итераторов) и двумя, которые мы имели в вопросе, используя math название. Так же, как показано ниже:

#include <iostream>
#include <vector>

template<typename T64> constexpr  T64 calcGCD(T64 a, T64 b)
{
return (a==0 && b!=0) ? b: a;
while(b)
{
T64 t = a % b;
b = a;
a = t;
}
return a;
}

template <typename Iterator> constexpr auto GCD(Iterator first, Iterator last)
{
auto itrFirst = first;
auto itrEnd   = last;
int Size      = std::distance(itrFirst,itrEnd);
int Result = 0;

if(Size >=2 )
{
int A       = *itrFirst;
std::advance (itrFirst,1);
int B       = *itrFirst;

Result      = calcGCD(A,B);
std::advance (itrFirst,1);

for(int i = 2; i<Size; ++i)
{
A       = *itrFirst;
Result  = calcGCD(Result,A);
std::advance (itrFirst,1);
}
}
else   return *itrFirst;
return Result;
}

namespace math
{
template <typename M, typename N>
constexpr auto GCD(const M& m, const N& n)
{ return calcGCD(m, n); }

template <typename M, typename ...Rest>
constexpr auto GCD(const M& first, const Rest&... rest)
{ return calcGCD(first, GCD(rest...));  }
}int main()
{
std::vector<int> vec={1,2,58,54,102,2,37,13,8};

std::cout<<"GCD from Iterator Template     : ";
for(unsigned int i=0; i<vec.size()-3; ++i)
std::cout<<GCD(vec.begin()+i, vec.begin()+i+4)<<" ";

std::cout<<std::endl;

std::cout<<"GCD from non-iterator Templates: ";
std::cout<<math::GCD(1,2,58,54)<<" ";
std::cout<<math::GCD(2,58,54,102)<<" ";
std::cout<<math::GCD(58,54,102,2)<<" ";
std::cout<<math::GCD(54,102,2,37)<<" ";
std::cout<<math::GCD(102,2,37,13)<<" ";
std::cout<<math::GCD(2,37,13,8)<<" ";

return 0;
}

Это дает требуемый результат, как и ожидалось. Тем не менее, я не проверял других случаев.

Выход:

GCD from Iterator Template     : 1 2 58 54 102 2
GCD from non-iterator Templates: 1 2 58 54 102 2
0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]