【问题标题】:template parameter is ambiguous / deduced conflicting types for parameter模板参数是模棱两可的/推断的参数冲突类型
【发布时间】:2020-05-11 19:26:36
【问题描述】:

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

  • MSVC:错误 C2782:“双点(const V &,const V &)”:模板参数“V”不明确
  • GCC:推断出参数“const V”(“Matrix”和“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());
}

【问题讨论】:

  • 不,我担心编译器(语言)没有那么复杂:它需要从不同类型的对象中推导出相同类型的V,所以会出现歧义错误。跨度>

标签: c++ templates compiler-errors c++14


【解决方案1】:

不,这不起作用。但实际上,你不需要模板

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,这仍然可能是模棱两可的。

【讨论】:

  • 我的问题中的代码是从一个更大的程序中提取的,用于测试错误。模板还有很多其他的实例。
  • 当然,关于孩子到基础的转换,你是对的..
  • @Museful 我更新了我的答案,所以它应该提供你需要的东西。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-31
  • 1970-01-01
  • 2018-07-07
  • 2015-02-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多