Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用运算符重载从模板类继承。用于'的不明确重载;操作员*';_C++_Templates_Inheritance - Fatal编程技术网

C++ 使用运算符重载从模板类继承。用于'的不明确重载;操作员*';

C++ 使用运算符重载从模板类继承。用于'的不明确重载;操作员*';,c++,templates,inheritance,C++,Templates,Inheritance,出于学习目的,我正在尝试使用模板类和继承。其中一件事是,我希望我的类能够使用操作符,例如+=,+,-=,-,*,*=,等等。为此,我开发了一个基本上是数据数组的类: template<typename T, int N> class Array { public: // Constructor Array( T value = T(0)) { /* Initialize the array with the same value everywh

出于学习目的,我正在尝试使用模板类和继承。其中一件事是,我希望我的类能够使用操作符,例如
+=
+
-=
-
*
*=
,等等。为此,我开发了一个基本上是数据数组的类:

template<typename T, int N>
class Array
{
public:
    // Constructor
    Array( T value = T(0))
    {
        /* Initialize the array with the same value everywhere */
    }
    template<typename M>
    Array(const Array<M,N>& other)
    {
        /* Copy constructor allowing for type change */
    }

    // Destructor
    ~Array()
    {
        /* no need to call any destructor since it is a smart pointer */    
    }

    // Product
    template<typename M>
    Array<T,N>& operator*=(const M& rhs)
    {
        /* implementation */
    }
    template<typename M>
    friend Array<T,N> operator*(const Array<T,N>& lhs,const M& rhs)
    {
        /* implementation */
    }
    template<typename M>
    friend Array<T,N> operator*( M lhs, const Array<T,N>& rhs)
    {
        /* implementation */
    }
    Array<T,N>& operator*=(const Array<T,N>& rhs)
    {
        /* implementation */
    }
    friend Array<T,N> operator*(const Array<T,N>& lhs,const Array<T,N>& rhs)
    {
        /* implementation */
    }

    // String
    std::string str() const
    {
        /* return a string containing the array */
    }

private:
    std::shared_ptr<T> data_;
    size_t n_;
};
模板
类数组
{
公众:
//建造师
数组(T值=T(0))
{
/*在所有位置使用相同的值初始化数组*/
}
样板
数组(常量数组和其他)
{
/*允许类型更改的复制构造函数*/
}
//析构函数
~Array()
{
/*无需调用任何析构函数,因为它是智能指针*/
}
//产品
样板
数组和运算符*=(常量M和rhs)
{
/*实施*/
}
样板
友元数组运算符*(常量数组和lhs、常量M和rhs)
{
/*实施*/
}
样板
友元数组运算符*(M lhs、常量数组和rhs)
{
/*实施*/
}
数组和运算符*=(常量数组和rhs)
{
/*实施*/
}
友元数组运算符*(常量数组和lhs、常量数组和rhs)
{
/*实施*/
}
//串
std::string str()常量
{
/*返回包含数组的字符串*/
}
私人:
std::共享的ptr数据;
大小;
};
我使用以下代码测试了这个类,没有任何问题:

// Test friend Array<T,N> operator*(const Array<T,N>& lhs,const Array<T,N>& rhs)
Array<double,2> array1(1);
std::cout<<"array1: "<<array1.str()<<std::endl;
Array<double,2> array2(2);
std::cout<<"array2: "<<array2.str()<<std::endl;
Array<int,2> array3 = array1*array2;
std::cout<<"array3: array1*array2"<<array3.str()<<std::endl;

// Test friend Array<T,N> operator*( M lhs, const Array<T,N>& rhs)
Array<double,2> array4 = 2*array1;
std::cout<<"array4: 2*array1"<<array4.str()<<std::endl;

// Test friend Array<T,N> operator*(const Array<T,N>& lhs,const M& rhs)
Array<double,2> array5 = array1*5;
std::cout<<"array5: array1*3"<<array5.str()<<std::endl;
//测试友元数组运算符*(常量数组和lhs、常量数组和rhs)
阵列1(1);

std::cout之所以会出现这些错误,是因为当编译器试图匹配运算符参数时,它将被迫对基类执行额外的向下转换,而在基类实例上调用相同的运算符时,它会得到精确的匹配。您应该使用
::std::enable_if
M
的类型设置额外的限制,如下所示:

template
<
     typename M
,    typename TEnable = typename ::std::enable_if_t
     <
         ::std::is_integral<M>::value
         ||
         ::std::is_floating_point<M>::value
     >
>
模板
<
类型名M
,typename TEnable=typename::std::启用
<
::std::is_integral::value
||
::std::是浮点::值
>
>

当您将*运算符声明为非成员友元函数模板时,
Array
类中没有
运算符*

在VTT提供了提示之后,我能够修复代码。因为我不使用c++14,所以我在没有
std::enable_if_t
的情况下成功地做到了这一点。以下是最终操作员:

// Product
template<typename M, typename std::enable_if<!std::is_base_of<Array<T,N>,M>::value>::type>
Array<T,N>& operator*=(const M& rhs)
{
    /* implementation */
}
template<typename M, typename std::enable_if<!std::is_base_of<Array<T,N>,M>::value>::type>
friend Array<T,N> operator*(const Array<T,N>& lhs,const M& rhs)
{
    /* implementation */
}
template<typename M, typename std::enable_if<!std::is_base_of<Array<T,N>,M>::value>::type>
friend Array<T,N> operator*( M lhs, const Array<T,N>& rhs)
{
    /* implementation */
}
Array<T,N>& operator*=(const Array<T,N>& rhs)
{
    /* implementation */
}
friend Array<T,N> operator*(const Array<T,N>& lhs,const Array<T,N>& rhs)
{
    /* implementation */
}
//产品
模板::值>::类型>
数组和运算符*=(常量M和rhs)
{
/*实施*/
}
模板::值>::类型>
友元数组运算符*(常量数组和lhs、常量M和rhs)
{
/*实施*/
}
模板::值>::类型>
友元数组运算符*(M lhs、常量数组和rhs)
{
/*实施*/
}
数组和运算符*=(常量数组和rhs)
{
/*实施*/
}
友元数组运算符*(常量数组和lhs、常量数组和rhs)
{
/*实施*/
}
希望这能帮助其他人

error: ambiguous overload for 'operator*' (operand types are 'Vector3<double>' and 'Vector3<double>')
     Vector3<int> vector3 = vector1*vector2;
                                   ^
note: candidates are:
note: Array<T, N> operator*(M, const Array<T, N>&) [with M = Vector3<double>; T = int; int N = 3]
     friend Array<T,N> operator*( M lhs, const Array<T,N>& rhs)
                       ^
note: Array<T, N> operator*(const Array<T, N>&, const M&) [with M = Vector3<double>; T = int; int N = 3]
     friend Array<T,N> operator*(const Array<T,N>& lhs,const M& rhs)
                       ^
note: Array<T, N> operator*(M, const Array<T, N>&) [with M = Vector3<double>; T = double; int N = 3]
     friend Array<T,N> operator*( M lhs, const Array<T,N>& rhs)
                       ^
note: Array<T, N> operator*(const Array<T, N>&, const M&) [with M = Vector3<double>; T = double; int N = 3]
     friend Array<T,N> operator*(const Array<T,N>& lhs,const M& rhs)
                       ^
note: Array<double, 3> operator*(const Array<double, 3>&, const Array<double, 3>&)
     friend Array<T,N> operator*(const Array<T,N>& lhs,const Array<T,N>& rhs)
                       ^
warning: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second: [enabled by default]
     Vector3<double> vector4 = 2*vector1;
                                 ^
note: candidate 1: Array<T, N> operator*(M, const Array<T, N>&) [with M = int; T = double; int N = 3]
     friend Array<T,N> operator*( M lhs, const Array<T,N>& rhs)
                       ^
note: candidate 2: Array<T, N> operator*(const Array<T, N>&, const M&) [with M = Vector3<double>; T = int; int N = 3]
     friend Array<T,N> operator*(const Array<T,N>& lhs,const M& rhs)
                       ^
warning: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second: [enabled by default]
     Vector3<double> vector4 = 2*vector1;
                                 ^
note: candidate 1: Array<T, N> operator*(M, const Array<T, N>&) [with M = int; T = double; int N = 3]
     friend Array<T,N> operator*( M lhs, const Array<T,N>& rhs)
                       ^
note: candidate 2: Array<T, N> operator*(const Array<T, N>&, const M&) [with M = Vector3<double>; T = double; int N = 2]
     friend Array<T,N> operator*(const Array<T,N>& lhs,const M& rhs)
                       ^
warning: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second: [enabled by default]
     Vector3<double> vector4 = 2*vector1;
                                 ^
note: candidate 1: Array<T, N> operator*(M, const Array<T, N>&) [with M = int; T = double; int N = 3]
     friend Array<T,N> operator*( M lhs, const Array<T,N>& rhs)
                       ^
note: candidate 2: Array<T, N> operator*(const Array<T, N>&, const M&) [with M = Vector3<double>; T = int; int N = 2]
     friend Array<T,N> operator*(const Array<T,N>& lhs,const M& rhs)
                       ^
warning: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second: [enabled by default]
     Vector3<double> vector4 = 2*vector1;
                                 ^
note: candidate 1: Array<T, N> operator*(M, const Array<T, N>&) [with M = int; T = double; int N = 3]
     friend Array<T,N> operator*( M lhs, const Array<T,N>& rhs)
                       ^
note: candidate 2: Array<T, N> operator*(const Array<T, N>&, const M&) [with M = Vector3<double>; T = double; int N = 3]
     friend Array<T,N> operator*(const Array<T,N>& lhs,const M& rhs)
                       ^
warning: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second: [enabled by default]
     Vector3<double> vector5 = vector1*5;
                                       ^
note: candidate 1: Array<T, N> operator*(const Array<T, N>&, const M&) [with M = int; T = double; int N = 3]
     friend Array<T,N> operator*(const Array<T,N>& lhs,const M& rhs)
                       ^
note: candidate 2: Array<T, N> operator*(M, const Array<T, N>&) [with M = Vector3<double>; T = int; int N = 3]
     friend Array<T,N> operator*( M lhs, const Array<T,N>& rhs)
                       ^
warning: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second: [enabled by default]
     Vector3<double> vector5 = vector1*5;
                                       ^
note: candidate 1: Array<T, N> operator*(const Array<T, N>&, const M&) [with M = int; T = double; int N = 3]
     friend Array<T,N> operator*(const Array<T,N>& lhs,const M& rhs)
                       ^
note: candidate 2: Array<T, N> operator*(M, const Array<T, N>&) [with M = Vector3<double>; T = double; int N = 2]
     friend Array<T,N> operator*( M lhs, const Array<T,N>& rhs)
                       ^
warning: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second: [enabled by default]
     Vector3<double> vector5 = vector1*5;
                                       ^
note: candidate 1: Array<T, N> operator*(const Array<T, N>&, const M&) [with M = int; T = double; int N = 3]
     friend Array<T,N> operator*(const Array<T,N>& lhs,const M& rhs)
                       ^
note: candidate 2: Array<T, N> operator*(M, const Array<T, N>&) [with M = Vector3<double>; T = int; int N = 2]
     friend Array<T,N> operator*( M lhs, const Array<T,N>& rhs)
                       ^
warning: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second: [enabled by default]
     Vector3<double> vector5 = vector1*5;
                                       ^
note: candidate 1: Array<T, N> operator*(const Array<T, N>&, const M&) [with M = int; T = double; int N = 3]
     friend Array<T,N> operator*(const Array<T,N>& lhs,const M& rhs)
                       ^
note: candidate 2: Array<T, N> operator*(M, const Array<T, N>&) [with M = Vector3<double>; T = double; int N = 3]
     friend Array<T,N> operator*( M lhs, const Array<T,N>& rhs)
                       ^
error: no members matching 'Array<double, 3>::operator*' in 'class Array<double, 3>'
     using Array<T,3>::operator*;
                               ^
template
<
     typename M
,    typename TEnable = typename ::std::enable_if_t
     <
         ::std::is_integral<M>::value
         ||
         ::std::is_floating_point<M>::value
     >
>
// Product
template<typename M, typename std::enable_if<!std::is_base_of<Array<T,N>,M>::value>::type>
Array<T,N>& operator*=(const M& rhs)
{
    /* implementation */
}
template<typename M, typename std::enable_if<!std::is_base_of<Array<T,N>,M>::value>::type>
friend Array<T,N> operator*(const Array<T,N>& lhs,const M& rhs)
{
    /* implementation */
}
template<typename M, typename std::enable_if<!std::is_base_of<Array<T,N>,M>::value>::type>
friend Array<T,N> operator*( M lhs, const Array<T,N>& rhs)
{
    /* implementation */
}
Array<T,N>& operator*=(const Array<T,N>& rhs)
{
    /* implementation */
}
friend Array<T,N> operator*(const Array<T,N>& lhs,const Array<T,N>& rhs)
{
    /* implementation */
}