Я пытаюсь получить что-то вроде перенаправления шаблонов на основе переменной прекомпилятора. Однако у меня возникают странные ошибки компиляции, поэтому я постараюсь привести пример того, над чем я работаю.

У меня есть матричный класс, который принимает два параметра шаблона, и способ его использования параметров шаблона основан на переменной прекомпилятора, которая определяет, находимся ли мы в среде с большим количеством столбцов или средой по строкам.

template
class Vector {
//... Implementation stuff
}

#define ROW_MAJOR

template
class Matrix {

#if defined(ROW_MAJOR)
std::array, rows> m_vectorArray;
#else
std::array, columns> m_vectorArray;
#endif

//... Other stuff
}

Как вы могли догадаться, это приводит к множеству операторов прекомпилятора # if и # else повсюду в моем коде, поэтому вместо этого я подумал о "пересылка" параметров шаблона в одном месте и обращение к этим параметрам шаблона. Например ...

#define ROW_MAJOR

template
class Matrix {

#if defined(ROW_MAJOR)
static constexpr size_t numberOfVectors = rows;
static constexpr size_t vectorLength = columns;
#else
static constexpr size_t numberOfVectors = columns;
static constexpr size_t vectorLength = rows;
#endif

std::array, numberOfVectors> m_vectorArray
//... Other stuff
}

И это прекрасно работало, пока мне не пришлось возвращать отдельные векторы. Я попытался объявить функцию внутри Matrix как таковую:

template
class Matrix {

//...Insert stuff from above
Vector GetVector(size_t index) const;
// ... Other stuff
}

А во включаемом файле функция была определена следующим образом:

template
Vector::vectorLength> Matrix::GetVector(size_t index) const
{
//... Implementation
}

И когда я пошел его компилировать, у меня была следующая ошибка

ошибка C2244: 'Matrix :: GetVector': невозможно сопоставить определение функции с существующим объявлением

Что, когда Visual Studio сообщает об этой ошибке, она пытается помочь мне, распечатав подпись определения и все подписи объявления функции GetVector.

note: definition
note: 'Vector::vectorLength> Matrix::GetVector(size_t index)'
note: existing declarations
note: 'Vector::vectorLength> Matrix::GetVector(size_t index)'

Два совпадающих символа для символа (я знаю, что это пример, но я скопировал и вставил обе заметки, которые я получаю в свой фактический код, сравнил их, и они соответствуют символу для символа), Итак, я предполагаю, что мой вопрос ... это неправильное использование constexpr? Я что-то забываю написать? Это ошибка компилятора Visual Studio (я уже столкнулся с множеством ошибок VS, связанных с constexpr). Или это глупый способ?

Некоторые примечания: Я попытался поместить определение в файл заголовка, и все скомпилировалось нормально. Это не проблема «не помещать определения шаблонов в файлы cpp», заголовочные и включаемые файлы объединены в один и тот же включаемый пакет, поэтому определение гарантированно будет там с определением класса.

Ответы (1)

Вероятно, еще одно проявление этой ошибки MSVC, хотя у нее есть вложенный тип, а здесь вы просто используете константу-член.

Используйте завершающий возвращаемый тип для обхода - он тоже короче:

auto Matrix::GetVector(size_t index) const
     -> Vector {
//...
}

Кроме того, вы можете просто написать vectorLength вместо Matrix :: vectorLength, если вы сделаете это в обоих местах.

2022 WebDevInsider