Параметр шаблона является неоднозначным / выведенным конфликтующих типов для параметра - PullRequest
0 голосов
/ 26 января 2020

Программа ниже генерирует ошибку компилятора:

  • MSV C: ошибка C2782: 'двойная точка (const V &, const V &)': параметр шаблона 'V' является неоднозначным
  • G CC: выведены конфликтующие типы для параметра 'const V' ('Matrix <3, 1>' и 'UnitVector')

Я думал, что он не будет иметь эта проблема, потому что конструктор UnitVector(Vector) помечен explicit, и, следовательно, аргументы (вызова dot()) могут быть разрешены только как Vector с неявными преобразованиями. Можете ли вы сказать мне, что я неправильно понимаю? Считает ли компилятор конструкторы explicit неявными преобразованиями при разрешении параметров шаблона?

template<int M, int N>
struct Matrix {
};

using Vector = Matrix<3,1>;

struct UnitVector : Vector{
    UnitVector(){}
    explicit UnitVector(const Vector& v)
    {}

    operator const Vector&(){
        return *static_cast<const Vector*>(this);
    }
};

template<typename V>
double dot(const V& a, const V& b){
    return 0.0;
}

int main()
{
    dot(Vector(),UnitVector());
}

1 Ответ

0 голосов
/ 26 января 2020

Нет, это не работает. Но на самом деле вам не нужен шаблон

double dot(const Vector &, const Vector &) {...}

работает. Вам даже не нужен оператор преобразования, определенный в UnitVector. Дочерние в базовые преобразования выполняются неявно.

Если вы хотите в общем случае взять два типа, которые неявно преобразуются в общий тип, следующее должно работать (не проверено)

template<class U>
double dot_impl(const U&, const U&) {...}

template<class U, class V>
auto dot(const U &u, const V &v) {
    return dot_impl<std::common_type_t<U, V>>(u, v);
}

Поскольку шаблон Параметр является явным, неявные преобразования в общий тип этих двух выполняются в вызове, поэтому все работает хорошо. Я переместил оригинал dot в dot_impl, так как в противном случае мы будем вызывать dot с одним параметром шаблона, который все еще может быть неоднозначным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...