Я делаю функцию для случайного заполнения двумерного массива. У меня есть класс Matrix(темплейтовый). Мне нужно в зависимости от типа данных который там находится поместить значение правильного типа.
Вот мой код:
void randomFill(int min = 0, int max = 10)
{
string typeID;
typeID = (string)(typeid(type).name());
for (size_t i = 0; i < row; i++)
{
for (size_t j = 0; j < col; j++)
{
if (typeID == "int") data[i][j] = rand() % (int)((max - min + 1) + min);
else if (typeID == "float") data[i][j] = rand() % (float)((max - min + 1) + min);
else if(typeID == "double") data[i][j] = rand() % (double)((max - min + 1) + min);
}
}
}
type — это тип текущего класа.
У меня вылетает следующая ошибка:
Ошибка C2760 синтаксическая ошибка: непредвиденный токен "идентификатор"; требуется ";"
Код целиком:
template <typename type>
class Matrix
{
private:
unsigned int row;
unsigned int col;
type** data;
public:
~Matrix()
{
for (size_t i = 0; i < row; i++)
{
delete[] data[i];
data[i] = nullptr;
}
data = nullptr;
}
Matrix(int row, int col)
{
data = new type * [row];
for (size_t i = 0; i < row; i++)
{
data[i] = new type[col];
}
this->row = row;
this->col = col;
}
Matrix(const Matrix<type>& elem) : Matrix(elem.row, elem.col)
{
for (size_t i = 0; i < row; i++)
{
for (size_t j
= 0; j < col; j++)
{
data[i][j] = elem.data[i][j];
}
}
}
template <typename type>
static void createArr2D(type**& init, int row, int col)
{
init = new type * [row];
for (size_t i = 0; i < row; i++)
{
init[i] = new type[col];
}
}
template <typename type>
static void DeleteArr2D(type**& init, int row)
{
for (size_t i = 0; i < row; i++)
{
delete[] init[i];
init[i] = nullptr;
}
init = nullptr;
}
static int MaxLenElemArr2D(type** init, int row, int col)
{
int res = 0;
for (size_t i = 0; i < row; i++)
{
for (size_t j = 0; j < col; j++)
{
if (std::to_string(init[i][j]).size() > res) res = std::to_string(init[i][j]).size();
}
}
return res;
}
friend std::ostream& operator<<(std::ostream& out, Matrix<type> p)
{
int maxLen = MaxLenElemArr2D(p.data, p.row, p.col);
for (size_t i = 0; i < p.row; i++)
{
for (size_t j = 0; j < p.col; j++)
{
out << std::setw(maxLen+2) << p.data[i][j];
}
out << std::endl;
}
return out;
}
friend std::istream& operator>>(std::istream& in, Matrix<type>& p)
{
for (size_t i = 0; i < p.row; i++)
{
COORD coord;
coord.Y = i + 1;
for (size_t j = 0; j < p.col; j++)
{
if (j == 0) coord.X = j + 1;
bool flag;
do
{
int tmp;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
in >> tmp;
p.data[i][j] = tmp;
int size_tmpElem = std::to_string(tmp).size();
if (in.fail())
{
in.clear();
in.ignore(32767, '\n');
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
for (size_t i = 0; i < 100; i++) std::cout << " ";
flag = true;
}
else
{
flag = false;
coord.X += size_tmpElem + 2;
}
} while (flag);
}
}
return in;
}
friend Matrix operator+(Matrix<type>& first, Matrix<type>& second)
{
/* if (first.row != second.col || first.row != second.row) return;*/
Matrix<type> tmp(first.row, first.col);
for (size_t i = 0; i < first.row; i++)
{
for (size_t j = 0; j < first.col; j++)
{
tmp.data[i][j] = first.data[i][j] + second.data[i][j];
}
}
return tmp;
}
friend Matrix operator-(Matrix<type>& first, Matrix<type>& second)
{
/* if (first.row != second.col || first.row != second.row) return;*/
Matrix<type> tmp(first.row, first.col);
for (size_t i = 0; i < first.row; i++)
{
for (size_t j = 0; j < first.col; j++)
{
tmp.data[i][j] = first.data[i][j] - second.data[i][j];
}
}
return tmp;
}
friend Matrix operator*(Matrix<type>& first, Matrix<type>& second)
{
/* if (first.row != second.col || first.row != second.row) return;*/
Matrix<type> tmp(first.row, first.col);
for (size_t i = 0; i < tmp.row; i++)
{
for (size_t j = 0; j < tmp.col; j++)
{
tmp.data[i][j] = first.data[i][j] * second.data[i][j];
}
}
return tmp;
}
friend Matrix operator/(Matrix<type>& first, Matrix<type>& second)
{
/* if (first.row != second.col || first.row != second.row) return;*/
Matrix<type> tmp(first.row, first.col);
for (size_t i = 0; i < first.row; i++)
{
for (size_t j = 0; j < first.col; j++)
{
if (second.data[i][j] == 0) tmp.data[i][j] = 0;
else tmp.data[i][j] = first.data[i][j] / second.data[i][j];
}
}
return tmp;
}
/*Matrix& operator=(Matrix<type>& second)
{
if (data != nullptr)
{
clear();
}
row = second.row;
col = second.col;
data = new type * [row];
for (size_t i = 0; i < col; i++)
{
data[i] = new type[col];
}
for (size_t i = 0; i < row; i++)
{
for (size_t j = 0; j < col; j++)
{
data[i][j] = second.data[i][j];
}
}
return *this;
}*/
Matrix& operator=(Matrix<type> second)
{
if (data != nullptr)
{
clear();
}
row = second.row;
col = second.col;
data = new type * [row];
for (size_t i = 0; i < col; i++)
{
data[i] = new type[col];
}
for (size_t i = 0; i < row; i++)
{
for (size_t j = 0; j < col; j++)
{
data[i][j] = second.data[i][j];
}
}
return *this;
}
friend bool operator==(Matrix<type>& first, Matrix<type>& second)
{
if (first.row != second.row || first.col != second.col) return false;
for (size_t i = 0; i < first.row; i++)
{
for (size_t j = 0; j < first.col; j++)
{
if (first.data[i][j] != second.data[i][j]) return false;
}
}
return true;
}
friend bool operator!=(Matrix<type>& first, Matrix<type>& second)
{
if (first.row != second.row || first.col != second.col) return true;
for (size_t i = 0; i < first.row; i++)
{
for (size_t j = 0; j < first.col; j++)
{
if (first.data[i][j] != second.data[i][j]) return true;
}
}
return false;
}
void clear()
{
for (size_t i = 0; i < row; i++)
{
delete[] data[i];
data[i] = nullptr;
}
data = nullptr;
row = 0;
col = 0;
}
void randomFill(int min = 0, int max = 10)
{
/*string typeID;
typeID = (string)(typeid(type).name());*/
for (size_t i = 0; i < row; i++)
{
for (size_t j = 0; j < col; j++)
{
data[i][j] = rand() % (int)((max - min + 1) + min);
/*if (typeID == "int") data[i][j] = rand() % (int)((max - min + 1) + min);
else if (typeID == "float") data[i][j] = rand() % (float)((max - min + 1) + min);
else if(typeID == "double") data[i][j] = rand() % (double)((max - min + 1) + min);*/
}
}
}
void print()
{
for (size_t i = 0; i < row; i++)
{
for (size_t j = 0; j < col; j++)
{
std::cout << std::setw(3) << data[i][j];
}
std::cout << std::endl;
}
}
void transposition()
{
type** NewData = new type * [col];
// создаем новый массив с реверсивным количеством строк и колонок
for (size_t i = 0; i < col; i++)
{
NewData[i] = new type[row];
}
// Перенос данных
for (size_t i = 0; i < row; i++)
{
for (size_t j = 0; j < col; j++)
{
NewData[j][i] = data[i][j];
}
}
// Очищаем прошлые данные
for (size_t i = 0; i < row; i++)
{
delete[] data[i];
data[i] = nullptr;
}
data = nullptr;
std::swap(row, col);
// Присваиваем указатель на старое место
data = NewData;
}
void KbInput(int posX = 0, int posY = 0)
{
for (size_t i = 0; i < row; i++)
{
COORD coord;
coord.Y = i + 1 + posY;
for (size_t j = 0; j < col; j++)
{
if (j == 0) coord.X = j + 1 + posX;
bool flag;
do
{
int tmp;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
std::cin >> tmp;
data[i][j] = tmp;
int size_tmpElem = std::to_string(tmp).size();
if (std::cin.fail())
{
std::cin.clear();
std::cin.ignore(32767, '\n');
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
for (size_t i = 0; i < 100; i++) std::cout << " ";
flag = true;
}
else
{
flag = false;
coord.X += size_tmpElem + 2;
}
} while (flag);
}
}
}
unsigned int getRow() const { return row; }
unsigned int getCol() const { return col; }
void DelRow(int pos)
{
if (pos < 0 || pos > row - 1) return;
type** NewData = new type * [row - 1];
createArr2D(NewData, row - 1, col);
if (pos != 0)
{
for (size_t i = 0; i < pos; i++)
{
for (size_t j = 0; j < col; j++)
{
NewData[i][j] = data[i][j];
}
}
}
for (size_t i = pos+1, i_posNew = pos; i < row ; i++, i_posNew++)
{
for (size_t j = 0, j_posNew = 0; j < col; j++, j_posNew++)
{
NewData[i_posNew][j_posNew] = data[i][j];
}
}
DeleteArr2D(data, row);
data = NewData;
row--;
}
void DelCol(int pos)
{
if (pos < 0 || pos > col - 1) return;
type** NewData;
createArr2D(NewData, row, col - 1);
if (pos != 0)
{
for (size_t i = 0; i < row; i++)
{
for (size_t j = 0; j < pos; j++)
{
NewData[i][j] = data[i][j];
}
}
}
for (size_t i = 0; i < row; i++)
{
for (size_t j = pos+1, j_NewData = pos; j < col; j++, j_NewData++)
{
NewData[i][j_NewData] = data[i][j];
}
}
DeleteArr2D(data, row);
data = NewData;
col--;
}
type findMaxElem()
{
type res = data[0][0];
for (size_t i = 0; i < row; i++)
{
for (size_t j = 0; j < col; j++)
{
if (data[i][j] > res) res = data[i][j];
}
}
return res;
}
type findMinElem()
{
type res = data[0][0];
for (size_t i = 0; i < row; i++)
{
for (size_t j = 0; j < col; j++)
{
if (data[i][j] < res) res = data[i][j];
}
}
return res;
}
void lineByline_Sort()
{
for (size_t i = 0; i < row; i++)
{
for (size_t j = 0; j < col-1; j++)
{
int min = j;
for (size_t b = j+1; b < col; b++)
{
if (data[i][b] < data[i][min])
min = b;
}
std::swap(data[i][j], data[i][min]);
}
}
}
void Full_Sort()
{
for (size_t i_swap = 0; i_swap < row; i_swap++)
{
for (size_t j_swap = 0; j_swap < col; j_swap++)
{
int row_min = i_swap;
int col_min = j_swap;
for (size_t i = row_min; i < row; i++)
{
if (i == row_min)
{
for (size_t j = col_min + 1; j < col; j++)
{
if (data[i][j] < data[row_min][col_min])
{
row_min = i;
col_min = j;
}
}
}
else
{
for (size_t j = 0; j < col; j++)
{
if (data[i][j] < data[row_min][col_min])
{
row_min = i;
col_min = j;
}
}
}
}
std::swap(data[i_swap][j_swap], data[row_min][col_min]);
/*std::cout << std::endl << std::endl;
print();*/
}
}
}
};
Search code, repositories, users, issues, pull requests…
Provide feedback
Saved searches
Use saved searches to filter your results more quickly
Sign up
ikazuchi 0 / 0 / 0 Регистрация: 20.11.2019 Сообщений: 10 |
||||
1 |
||||
05.12.2021, 13:05. Показов 4216. Ответов 4 Метки с++ iterator (Все метки)
ругается вот на эту строчку: for (list<Node>::iterator j = edgeList[i].begin(); j != edgeList[i].end(); ++j);
0 |
фрилансер 4909 / 4550 / 960 Регистрация: 11.10.2019 Сообщений: 11,914 |
|
05.12.2021, 14:52 |
2 |
ikazuchi, точка с запятой в конце строки вроде не нужна
0 |
0 / 0 / 0 Регистрация: 20.11.2019 Сообщений: 10 |
|
05.12.2021, 16:26 [ТС] |
3 |
не знаю как она там появилась… но все равно не работает(
0 |
volvo Супер-модератор 32627 / 21094 / 8139 Регистрация: 22.10.2011 Сообщений: 36,356 Записей в блоге: 8 |
||||
05.12.2021, 18:07 |
4 |
|||
РешениеА что, VS typename не требует? Странно, по Стандарту, вроде, нужно… Попробовал вот так:
, gcc ошибок не дает.
1 |
Алексей1153 фрилансер 4909 / 4550 / 960 Регистрация: 11.10.2019 Сообщений: 11,914 |
||||
05.12.2021, 21:49 |
5 |
|||
ikazuchi, или так
0 |
I’m trying to include the following definitions for GDI+ into my Win32 C++ project that is compiled under Visual Studio 2017:
#include <objidl.h>
#include <gdiplus.h>
#pragma comment (lib,"Gdiplus.lib")
I need to compile this project to support Windows XP. So in the project properies I selected: Platform Toolset
as Visual Studio 2017 - Windows XP (v141_xp)
:
But when I compile it the GDI+ library gives me this:
1>c:\program files (x86)\microsoft sdks\windows\v7.1a\include\objbase.h(239): error C2760: syntax error: unexpected token 'identifier', expected 'type specifier'
1>c:\program files (x86)\microsoft sdks\windows\v7.1a\include\gdiplusheaders.h(891): error C4596: 'EmfToWmfBits': illegal qualified name in member declaration
1>c:\program files (x86)\microsoft sdks\windows\v7.1a\include\gdiplusstringformat.h(220): error C4596: 'GetTrimming': illegal qualified name in member declaration
Any idea how to fix this?
asked Jul 12, 2019 at 22:41
1
Add this line before the very first(!) #include
of COM-related header to fix objbase.h(239): error C2760: syntax error: unexpected token 'identifier', expected 'type specifier'
:
typedef struct IUnknown IUnknown;
This fix works, because the line in objbase.h(239)
mentioned in the error contains static_cast<IUnknown*>(*pp);
despite that IUnknown still haven’t been declared in that place.
answered Jun 12, 2020 at 17:31
Кое КтоКое Кто
4455 silver badges9 bronze badges
I kinda got it to compile, but this is definitely not a good solution. I’m posting it here as a temp workaround until Microsoft gets their heads out of their ___es. Also if anyone finds a better way, please let me know.
I basically had to downgrade the entire project to Visual Studio 2015 - Windows XP (v140_xp)
just to compile one badly written library:
This created a problem of its own with the std
libraries:
1>C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\cstdio(50): error C4995: 'sprintf': name was marked as #pragma deprecated
1>C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\cstdio(53): error C4995: 'vsprintf': name was marked as #pragma deprecated
1>C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\cstring(20): error C4995: 'strcat': name was marked as #pragma deprecated
1>C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\cstring(21): error C4995: 'strcpy': name was marked as #pragma deprecated
1>C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\cwchar(29): error C4995: 'swprintf': name was marked as #pragma deprecated
1>C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\cwchar(30): error C4995: 'vswprintf': name was marked as #pragma deprecated
1>C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\cwchar(32): error C4995: 'wcscat': name was marked as #pragma deprecated
1>C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\cwchar(34): error C4995: 'wcscpy': name was marked as #pragma deprecated
So I had to shunt those errors of unsafe functions:
#pragma warning( push )
#pragma warning( disable: 4995 )
#include <stdio.h>
#include <new>
#include <string>
#pragma warning( pop )
Which is far from ideal!
(You’re basically sacrificing security of the app just to compile that damn GDI+ library.)
answered Jul 13, 2019 at 20:57
c00000fdc00000fd
21.1k30 gold badges177 silver badges403 bronze badges
1
There’s a way to get this to work if you’re prepared to edit the Windows header files.
In objbase.h
, comment out line 239 or change it to:
static_assert (std::is_base_of <IUnknown *, *pp>::value, "pp must derive from IUnknown");
In gdiplusheaders.h
, line 891, remove the redundant qualifier (Metafile::
).
In gdiplusstringformat.h
, line 220, remove the redundant qualifier (StringFormat::
).
Hopefully, that will fix things for you without breaking anything.
answered Jul 13, 2019 at 23:23
Paul SandersPaul Sanders
24.1k4 gold badges26 silver badges49 bronze badges
1
Although the question is old, just adding what worked for me.
In my case including windows.h and compiling with VS2017 v141_xp toolset was causing me error: syntax error: unexpected token ‘identifier’, expected ‘type specifier’.
This resolved my issue link
answered Jul 15, 2021 at 15:43
используя VS2017 и код:
template <typename T>
void showset(vector<T> v)
{
for (vector<T>::iterator it = v.begin(); it != v.end(); it++)
{
cout << *it;
}
cout << endl;
}
ошибка:
ошибка C2760: синтаксическая ошибка: неожиданный токен, ожидаемый ‘;’
Вопрос в том, как использовать итератор шаблона.
3
Решение
Во-первых, обратите внимание, что если имеется в виду зависимое имя аргумента шаблона лайк vector<T>::iterator
здесь, то вам нужно положить typename
до. Кроме того, зависит от того, что T
будет компилироваться, только если std::cout
«s operator<<
принимает это T
, Это, например, компилируется просто отлично:
#include <iostream>
#include <vector>
template <typename T>
void showset(std::vector<T> v)
{
for (typename std::vector<T>::iterator it = v.begin(); it != v.end(); it++)
{
std::cout << *it;
}
std::cout << std::endl;
}
struct foo
{
};
int main()
{
showset(std::vector<int>{1,2,3});
//showset(std::vector<foo>{}); // Error: `cout` doesn't take `foo`s.
return 0;
}
С auto
-улучшенный синтаксис C ++ 11, showset()
можно написать так, а затем typename
не имеет смысла 🙂
template <typename T>
void showset(std::vector<T> v)
{
for (auto it = v.begin(); it != v.end(); it++)
{
std::cout << *it;
}
std::cout << std::endl;
}
Также, начиная с C ++ 11, вы можете использовать Диапазон на основе за петля добиться того же, что и в исходном фрагменте:
template <typename T>
void showset(std::vector<T> v)
{
for (auto& ref : v)
{
std::cout << ref;
}
std::cout << std::endl;
}
Как и в версии Lase, потому что вы не имеете в виду здесь iterator
типа нечего ставить typename
за.
Обратите внимание, что в обеих версиях вы принимаете параметр v
по значению. Следовательно, вы копируете весь вектор для каждого вызова функции. Поскольку код приведен в вопросе, кажется, нет никаких причин для этого, поэтому вы должны передать его по ссылке и сделать его const
один, так как вы не модифицируете v
где-нибудь внутри showset()
:
void showset(const std::vector<T>& v);
а затем в нена основе диапазона для цикла версия не забудьте изменить оператор цикла соответственно:
for (typename std::vector<T>::const_iterator it = v.begin(); it != v.end(); it++)
4
Другие решения
Хороший подход к этому выглядит так:
template <typename T>
void showset(const T& v)
{
for (auto const &x : v)
{
cout << x;
}
cout << endl;
}
Или без петли диапазона:
template <typename T>
void showset(const T& v)
{
for (auto it = std::begin(v); it != std::end(v); ++it)
{
cout << *it;
}
cout << endl;
}
редактировать:
Но я обычно использую что-то более сложное. Более или менее это выглядит так:
template<typename T>
class LogContainerHelper {
LogContainerHelper(const T& v
size_t maxFront,
size_t maxTail)
: mContainer{ v }
, mMaxFront{ maxFront }
, mMaxTail{ maxTail }
{}
std::ostream &printTo(std::ostream &out) const {
// here I usually have something more complex
// depending on mMaxFront and mMaxTail values,
// don't have time to recreate that now
auto it = std::begin(mContainer);
auto end = std::end(mContainer);
out << '[';
if (it != end) {
out << *it;
++it;
}
for (; it != end; ++it)
{
out << ", " << *it;
}
return out << ']';
}
private:
const T &mContainer;
size_t mMaxFront;
size_t mMaxTail;
};
template<typename T>
std::ostream &operator <<(std::ostream &out, const LogContainerHelper<T> &helper) {
return helper.printTo(out);
}
template<typename T>
auto LogContainer(const T& v,
size_t maxFront = std::numeric_limits<size_t>::max(),
size_t maxTail = 0)
-> LogContainerHelper<T> {
return LogContainerHelper<T>{ v, maxFront, maxTail };
}
Итак, позже я могу сделать это:
cout << "Main containter is: " << LogContainer(v) << '\n';
2