模板函数的参数未进行任何隐式转换

问题描述

|| 由于某些奇怪的原因,我无法在这段代码中将模板参数隐式转换为兼容类型。
#include <type_traits>

template <typename T,unsigned D>
struct vec;

template <>
struct vec<float,2> {
    typedef float scalar;
    static constexpr unsigned dimension = 2;

    float x,y;
    float&       operator[] (unsigned i)       { return (&x)[i]; }
    float const& operator[] (unsigned i) const { return (&x)[i]; }
};


template <typename L,typename R>
struct add;

template <typename L,typename R,unsigned D>
struct add<vec<L,D>,vec<R,D>> {
    typedef vec<L,D> left_type;
    typedef vec<R,D> right_type;
    typedef vec<typename std::common_type<L,R>::type,D> return_type;

    add(left_type l,right_type r)
        : left(l),right(r)
    {}

    operator return_type() const
    {
        return_type result;
        for (unsigned i = 0; i < D; ++i)
            result[i] = left[i] + right[i];
        return result;
    }

    left_type  left;
    right_type right;
};


template <typename L,unsigned D>
add<vec<L,D>>
operator+(vec<L,D> const& lhs,D> const& rhs)
{
    return {lhs,rhs};
}


int main()
{
    vec<float,2> a,b,c;
    vec<float,2> result = a + b + c;
}
失败:
prog.cpp: In function \'int main()\':
prog.cpp:55:36: error: no match for \'operator+\' in \'operator+ [with L = float,R = float,unsigned int D = 2u](((const vec<float,2u>&)((const vec<float,2u>*)(& a))),((const vec<float,2u>*)(& b)))) + c\'
因此,如果我是正确的,则编译器应在主函数中看到如下代码:
((a + b) + c)
计算
a + b
使用
add<...>
中的转换运算符将
a + b
的结果从
add<...>
转换为
vec<float,2>
计算
(a + b) + c
但是它永远不会执行隐式转换。如果我将(a + b)的结果显式转换为vec,则代码可以正常工作。     

解决方法

        我将回避您的实际问题并提出建议:与其从头开始编写所有复杂的样板,不如看一下Boost.Proto,它为您处理了所有棘手的细节:   Proto是用于在C ++中构建特定于域的嵌入式语言的框架。它提供了用于构建,类型检查,转换和执行表达式模板的工具。更具体地说,Proto提供:         表达式树数据结构。   一种给予表达式其他行为和成员的机制。   运算符用于从表达式构建树的重载。   定义表达式必须符合的语法的实用程序。   立即执行表达式模板的可扩展机制。   一组可扩展的树变换,可应用于表达式树。    另请参见库作者的Expressive C ++系列文章,这些文章或多或少地充当了(出色的)深度Boost.Proto教程。     ,        模板参数推导过程中不使用大多数转换。 调用
operator+
重载时,您依靠模板参数推导:只有两个参数都为
vec<...>
类型时,才可以调用,但是当您尝试调用它时,左侧参数为
add<...>
类型。编译器无法弄清楚您的意思是要调用该重载(并且不允许猜测),因此会出现错误。     

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...