Вторая лямбда-функция в шаблоне вызывает ошибку компиляции (intellisense не обнаруживает проблем) — ошибка C2988

#c #templates #visual-c #lambda #c 17

#c #шаблоны #visual-c #лямбда #c 17

Вопрос:

Я использую последнюю версию C (думаю, это что-то среднее между C 17 и C 20), доступную в Visual Studio enterprise 16.8 (но эта ошибка возникает и в предыдущих версиях).

Следующая часть кода работает корректно, если исключить SquareMatrixInput<T> input_func = [](bool latest) { T temp; cin >> temp; return temp; } из шаблона (конечно, я также исключаю SquareMatrixInput<T> из кода классов). Intellitrace удовлетворен, но компилятор ругается.

Вывод компилятора:

 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'
  

Код:

 #include <iostream>

using namespace std;

template<typename T>
using SquareMatrixPrint = void (*)(const Tamp; item, bool latest);

template<typename T>
using SquareMatrixInput = T (*)(bool latest);

template<typename T = int, 
    SquareMatrixPrint<T> print_func = [](const T amp;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> amp;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>amp; operator=(const SquareMatrix<U, pf, fi> amp;sqm) {
        if (this == amp;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;
}
  

Следующий код (если я удаляю значения по умолчанию из шаблона) работает:

 int main() {
    SquareMatrix<int, [](const int amp;item, bool latest) { cout << item << (latest ? 'n' : 't'); },
        [](bool latest) { int temp; cin >> temp; return temp; } > sq(4);
    
    return 0;
}
  

Ответ №1:

Привет: это связано с ошибкой в Visual C , и причиной является проблема, упомянутая выше — компилятор обрабатывает ‘>>’ в качестве ограничителя для списка параметров шаблона. Ошибка исправлена и должна появиться в следующем обновлении Visual C 2019.

Ответ №2:

Я думаю, что это ошибка в компиляторе Visual Studio (я могу воспроизвести с Community Edition 2019). У Clang-cl нет проблем с вашим кодом.

Проблема, по-видимому, заключается в том, что компилятор сбит с толку >> оператором в cin >> temp; и может быть исправлена путем заключения этой операции в круглые скобки, например:

 template<typename T = int,
    SquareMatrixPrint<T> print_func = [](const Tamp; item, bool latest) { cout << item << (latest ? 'n' : 't'); },
    SquareMatrixInput<T> input_func = [](bool) { T temp; (cin >> temp); return temp; } >
    class SquareMatrix {
    //...
  

Ответ №3:

Проблема синтаксического анализа в параметре шаблона с cin >> temp;

>> (ошибочно) интерпретируется как закрывающие угловые скобки шаблона.

Вы должны поставить дополнительные круглые скобки:

(cin >> temp;)

ДЕМОНСТРАЦИЯ