Reputation: 452
I'm using the latest version of C++ (guess it is something between C++17 and C++20) available in visual studio enterprise 16.8 (but this error happening on previous versions too).
The following part of the code works correctly if exclude SquareMatrixInput<T> input_func = [](bool latest) { T temp; cin >> temp; return temp; }
from the template (of course, I'm also exclude SquareMatrixInput<T>
from classes code).
Intellitrace satisfied, but the compiler swears.
Compiler's output:
error C2958: the left brace '{' found at 'my_code.cpp' was not matched correctly
error C2988: unrecognizable template declaration/definition
error C2059: syntax error: '>'
error C2988: unrecognizable template declaration/definition
error C2059: syntax error: 'return'
error C2988: unrecognizable template declaration/definition
error C2059: syntax error: '}'
error C2143: syntax error: missing ';' before '}'
error C7568: argument list missing after assumed function template 'SquareMatrix'
Code:
#include <iostream>
using namespace std;
template<typename T>
using SquareMatrixPrint = void (*)(const T& item, bool latest);
template<typename T>
using SquareMatrixInput = T (*)(bool latest);
template<typename T = int,
SquareMatrixPrint<T> print_func = [](const T &item, bool latest) { cout << item << (latest ? '\n' : '\t'); },
SquareMatrixInput<T> input_func = [](bool latest) { T temp; cin >> temp; return temp; } >
class SquareMatrix {
uint8_t grade;
uint16_t size;
T *items;
public:
explicit SquareMatrix(uint8_t grade) {
if (grade < 2) {
throw new exception();
}
this->grade = grade;
size = grade * grade;
items = new T[size]{};
}
const T *operator[] (uint8_t i) const {
return items + i * grade;
}
template <typename U, SquareMatrixPrint<U> pf, SquareMatrixInput<U> fi>
SquareMatrix(const SquareMatrix<U, pf, fi> &sqm) {
grade = sqm.GetGrade();
size = grade * grade;
items = new T[size];
T *citem = items;
for (uint8_t i = 0, j; i != grade; ++i) {
for (j = 0; j != grade; ++j) {
*citem = sqm[i][j];
++citem;
}
}
}
template <typename U, SquareMatrixPrint<U> pf, SquareMatrixInput<U> fi>
const SquareMatrix<T, print_func, input_func>& operator=(const SquareMatrix<U, pf, fi> &sqm) {
if (this == &sqm) return *this;
if (grade != sqm.GetGrade()) {
grade = sqm.GetGrade();
size = grade * grade;
delete[] items;
items = new T[size];
}
T *citem = items;
for (uint8_t i = 0, j; i != grade; ++i) {
for (j = 0; j != grade; ++j) {
*citem = sqm[i][j];
++citem;
}
}
return *this;
}
~SquareMatrix() {
delete[] items;
}
};
int main() {
SquareMatrix<> sq(4);
return 0;
}
The next code (if I removing defaults from the template) works:
int main() {
SquareMatrix<int, [](const int &item, bool latest) { cout << item << (latest ? '\n' : '\t'); },
[](bool latest) { int temp; cin >> temp; return temp; } > sq(4);
return 0;
}
Upvotes: 1
Views: 445
Reputation: 21
Hi: this is due to a bug in Visual C++ and the cause is the issue mentioned above - the compiler is treating '>>' as the terminator for the template parameter list. The bug has been fixed and should show up in the next update to Visual C++ 2019.
Upvotes: 2
Reputation: 217283
Parsing issue in template parameter with cin >> temp;
>>
is (wrongly) interpreted as closing angle brackets of the template.
You have to put extra parenthesis:
(cin >> temp;)
Upvotes: 0
Reputation: 51835
I think it's a bug in the Visual Studio compiler (I can reproduce with Community Edition 2019). Clang-cl has no problem with your code.
The problem appears to be that the compiler is confused by the >>
operator in cin >> temp;
and can be fixed by enclosing that operation in parentheses, like so:
template<typename T = int,
SquareMatrixPrint<T> print_func = [](const T& item, bool latest) { cout << item << (latest ? '\n' : '\t'); },
SquareMatrixInput<T> input_func = [](bool) { T temp; (cin >> temp); return temp; } >
class SquareMatrix {
//...
Upvotes: 0