У меня есть шаблон матрицы класса:Как разрешить этот неоднозначный вызов конструктора шаблонов?
#include <iostream>
#include <array>
#include <initializer_list>
#include <utility>
#include <type_traits>
#include <cstddef>
enum ColumnFill {
COLUMNS
};
template <typename T, std::size_t M, std::size_t N>
struct TMatrixMxN {
TMatrixMxN(T x = T(0)) {
std::cout << "Default" << std::endl;
}
TMatrixMxN(std::initializer_list<T> values) {
std::cout << "Row initializer" << std::endl;
}
TMatrixMxN(std::initializer_list<T> values, ColumnFill dummy) {
std::cout << "Column initializer" << std::endl;
}
TMatrixMxN(std::initializer_list<std::initializer_list<T>> values) {
std::cout << "Value initializer" << std::endl;
}
TMatrixMxN(const std::array<std::array<T, N>, M> &values) {
std::cout << "From array" << std::endl;
}
TMatrixMxN(const TMatrixMxN<T, M - 1, N - 1> &x) {
std::cout << "From lower dimension" << std::endl;
}
TMatrixMxN(const TMatrixMxN &x) {
std::cout << "Copy" << std::endl;
}
TMatrixMxN(TMatrixMxN &&x) {
std::cout << "Move" << std::endl;
}
};
typedef TMatrixMxN<float, 1, 1> Matrix1x1;
typedef TMatrixMxN<float, 2, 2> Matrix2x2;
typedef TMatrixMxN<float, 3, 3> Matrix3x3;
typedef TMatrixMxN<float, 3, 1> Matrix3x1;
денди Everything, пока я не использовать матрицу, которая имеет 1 в любой из его размеров:
int main() {
std::array<std::array<float, 3>, 3> arr{{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}};
Matrix3x3 m1;
Matrix3x3 m2({1, 2, 3});
Matrix3x3 m3({1, 2, 3}, COLUMNS);
Matrix3x3 m4({{1, 2, 3}, {4, 5, 6}, {7, 8, 9}});
Matrix3x3 m5(arr);
Matrix3x3 m6(Matrix2x2({{1, 2}, {3, 4}}));
Matrix3x3 m7(m6);
Matrix3x3 m8(std::move(m7));
std::cout << std::endl;
TMatrixMxN<float, 3, 2>({{1, 2}, {3, 4}, {5, 6}});
std::cout << std::endl;
// PROBLEMS:
Matrix3x1({{1}, {2}, {3}}); // error: ambiguous
Matrix1x1({{1}}); // error: ambiguous
}
Я не знаю, как красиво решить эту проблему (Я хочу, чтобы эти вызовы назвать стоимостью инициализатора конструктора)
при компиляции с g++ -std=c++11 Ambiguous.cpp
, компилятор считает, что следующие конструкторами являются кандидатами для 3х1 матрицы: двигаться, копию, из-низшего измерения, стоимость инициализатор, рядного инициализатор. Для матрицы 1x1 также перечислены из массива и по умолчанию.
Что я пробовал:
- Использование SFINAE, чтобы состояние перегрузки, что T должен быть арифметический тип (
std::is_arithmetic
), потому что я думал, что это иногда может подумать, что этоinitializer_list
, но ничего не изменил. Я понял, что это бесполезно проверка, так как он на самом деле уже знает хорошо, и хорошо, что Т поплавок в этом примере - Добавление
explicit
ключевого слова в эти конструкторы: ценностных инициализатору, рядного инициализатор, колонного инициализатора , из-массива и от нижележащего измерении, потому что я думал, что есть некоторые неявные вызовы происходит, но и ничего не - Making ЬурейуЮ «фил» изменить (как «список инициализатора поплавка ») и преобразование кода в
{fil{1}}
, так как я понял, что готовый материал не может t интерпретироваться как список инициализаторов - тогда он работал по назначению. Однако я не думаю, что это исправление достаточно хорошо.
Можно ли это вообще сделать?
Спасибо! :) Не могли бы вы показать мне, как я мог сделать это с помощью enable_if_t? –
@ComradeBearabyte Смотрите править. – Barry
Я вижу, я сделал то же самое, за исключением того, что я не добавлял новые параметры шаблона (m = M, n = N) и просто использовал M и N, но это не помогло. Не могли бы вы объяснить, почему мне нужно новое параметры шаблона? –