Gremlin92
@Gremlin92
Целеустремленный

Как скормить компилятору такую шляпу?

#pragma once
#include <iostream>
#include <list>
#include <vector>

#include <iterator>
template <typename T> class Sorts
{
public:
	std::list<T> arrayList;
	std::vector<T> bubbleArray,insertionArray,heapArray,shakeArray;
	std::vector<T> BubbleSort()
	{
		std::cout <<"Time to Bubble>" << std::endl;
		unsigned int start_time = clock(); // начальное время
		int size = bubbleArray.size();
		for (int i = 1; i < size; i++)
			for (int j = size-1; j >=i; j--)
				if (bubbleArray[j-1] > bubbleArray[j])
					swap(bubbleArray, j - 1, j);
		unsigned int end_time = clock(); // конечное время
		unsigned int search_time = end_time - start_time; // искомое время
		std::cout << (float)search_time / CLOCKS_PER_SEC << std::endl;
		return bubbleArray;
	}
	std::vector<T> InsertionSort()
	{
		std::cout << "Time to Insertion>" << std::endl;
		unsigned int start_time = clock(); // начальное время
		int size = insertionArray.size();
		for (int i = 1; i < size; i++)
		{
			T tmp = insertionArray[i];
			int j = i;
			while (j > 0 && insertionArray[j - 1] > tmp)
			{
				insertionArray[j] = insertionArray[j - 1];
				j = j - 1;
			}
			insertionArray[j] = tmp;
		}
		unsigned int end_time = clock(); // конечное время
		unsigned int search_time = end_time - start_time; // искомое время
		std::cout << (float)search_time / CLOCKS_PER_SEC << std::endl;
		return insertionArray;
	}
	void swap(std::vector<T> v, int n, int m)
	{
		T tmp = v[n];
		v[n] = v[m];
		v[m] = tmp;
	}
	std::vector<T> HeapSort()
	{
		std::cout << "Time to Heap>" << std::endl;
		unsigned int start_time = clock(); // начальное время
		int size = heapArray.size();
		for (int j = 0; j < size; j++)
		{
			for (int i = size / 2 - 1 - j / 2; i > -1; i--)
			{
				if (2 * i + 2 <= size - 1 - j)
				{
					if (heapArray[2 * i + 1] > heapArray[2 * i + 2])
					{
						if (heapArray[i] < heapArray[2 * i + 1])
						{
							swap(heapArray, i, 2 * i + 1);
						}
					}
					else
						if (heapArray[i] < heapArray[2 * i + 2])
						{
							swap(heapArray, i, 2 * i + 2);
						}
				}
				else
					if (2 * i + 1 <= size - 1 - j)
						if (heapArray[i] < heapArray[2 * i + 1])
							swap(heapArray, i, 2 * i + 1);
			}
			swap(heapArray, 0, size - 1 - j);
		}
		unsigned int end_time = clock(); // конечное время
		unsigned int search_time = end_time - start_time; // искомое время
		std::cout << (float)search_time / CLOCKS_PER_SEC << std::endl;
		return heapArray;
	}
	std::vector<T> ShakeSort()
	{
		std::cout << "Time to Shake>" << std::endl;
		unsigned int start_time = clock(); // начальное время
		int size = shakeArray.size();
		int left = 0;
		int right = size - 1;
		do {
			for (int i = left; i < right; i++) {
				if (shakeArray[i] > shakeArray[i + 1])
					swap(shakeArray,i,i+1);
			}
			right--;
			for (int i = right; i > left; i--) {
				if (shakeArray[i] < shakeArray[i - 1])
					swap(shakeArray, i-1, i);
			}
			left++;
		} while (left < right);
		unsigned int end_time = clock(); // конечное время
		unsigned int search_time = end_time - start_time; // искомое время
		std::cout << (float)search_time / CLOCKS_PER_SEC << std::endl;
		return shakeArray;
	}
	void PrintArray(int num)
	{
		switch (num)
		{
		case 0:
			for (std::list<T>::iterator it = arrayList.begin(); it != arrayList.end(); it++)
				std::cout << (*it) << " ";
			break;
		case 1:
			for (std::vector<T>::iterator it = bubbleArray.begin(); it != bubbleArray.end(); it++)
				std::cout << (*it) << " ";
			break;
		case 2:
			for (std::vector<T>::iterator it = shakeArray.begin(); it != shakeArray.end(); it++)
				std::cout << (*it) << " ";
			break;
		case 3:
			for (std::vector<T>::iterator it = heapArray.begin(); it != heapArray.end(); it++)
				std::cout << (*it) << " ";
			break;
		case 4:
			for (std::vector<T>::iterator it = insertionArray.begin(); it != insertionArray.end(); it++)
				std::cout << (*it) << " ";
			break;
		default:
			break;
		
		}
		std::cout << std::endl;
	}
};



int main()
{
	const int iSize = 10;
	auto sort = new Sorts<int>();
	srand(time(0));
	for (int i = 0; i < iSize; i++)
	{
		sort->arrayList.push_back(rand() % iSize);
	}
	sort->BubbleSort();
	sort->ShakeSort();
	sort->HeapSort();
	sort->InsertionSort();

	sort->PrintArray(1);
	sort->PrintArray(2);
	sort->PrintArray(3);
	sort->PrintArray(4);
	return 0;
}

Ругается на итераторы
  • Вопрос задан
  • 134 просмотра
Решения вопроса 1
@romancelover
программист C++ под Linux
У меня компилятор (g++ 10.2.0) сам подсказывает, чего не хватает:
test.cpp: В конкретизации «void Sorts::PrintArray(int) [с T = int]»:
test.cpp:161:21: required from here
test.cpp:118:26: ошибка: зависимое имя «std::__cxx11::list::iterator» разбирается как не тип, но конкретизация дает тип
118 | for (std::list::iterator it = arrayList.begin(); it != arrayList.end(); it++)
| ^~~~~~~~
test.cpp:118:26: замечание: задайте «typename std::__cxx11::list::iterator», если подразумевается тип

И так во во всех четырёх местах с итераторами. Это связано с тем, что std::list::iterator - это не обычный тип, а шаблонный, а по правилам языка С++ требуется указывать, что этот шаблон должен разбираться именно как тип.

Это нужно потому, что не всегда возможно определить, является ли подстановка шаблона типом или значением.
void foo(const T& t)
{
   // declares a pointer to an object of type T::bar
   T::bar * p;
}

struct StructWithBarAsType
{
   typedef int bar;
};

struct StructWithBarAsValue
{
    static int bar;
};

Непонятно, T::bar это тип или значение? Если в шаблон передать StructWithBarAsType, то это могло бы быть типом, если StructWithBarAsValue - то значением. Поэтому по умолчанию компилятор принимает такую запись за значение (а раз такого члена iterator в std::vector нет, то компилятор ругается на это), а если указать typename, то он будет знать, что это именно тип.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы