c++ - 模板参数模棱两可/推导了参数的冲突类型

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

下面的程序生成一个编译器错误:

  • MSVC:错误C2782:'双点(const V&,const V&)':模板参数'V'不明确
  • GCC:推导了参数'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());
    }
    

    最佳答案

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

    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);
    }
    

    由于template参数是显式的,因此在调用中完成了对这两种类型的通用类型的隐式转换,因此一切正常。我将原始dot移到dot_impl,因为否则我们将使用一个模板参数来调用dot,该参数仍然可能是模棱两可的。

    关于c++ - 模板参数模棱两可/推导了参数的冲突类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59913880/

    相关文章:

    C++多重继承私有(private)成员冲突

    c++ - 具有非类型模板参数的多态性

    Java 字数统计 : Error: Cannot find symbol. Java 编译器

    c++ - 前缀计算器——在某些情况下不起作用——C++

    c++ - 编译 C++ 程序时出错

    c++ - QML FontLoader 不工作

    c++ - Linux C++ 编译错误

    c++ - 使用动态转换的 Lambda

    compiler-errors - 无法编译 x86_64 .s 和 .c 文件 : undefined reference to function

    java - 运行我的java代码时得到 "Program has stopped "