首页 > 解决方案 > 模板参数是模棱两可的/推断的参数冲突类型

问题描述

下面的程序会产生编译器错误:

我原以为它不会有这个问题,因为构造函数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());
}

标签: c++templatescompiler-errorsc++14

解决方案


不,那是行不通的。但实际上,您不需要模板

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使用一个模板参数进行调用,这仍然可能是模棱两可的。


推荐阅读