Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/131.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++ 隐式构造函数是';t使用模板调用用户定义的运算符_C++_Templates - Fatal编程技术网

C++ 隐式构造函数是';t使用模板调用用户定义的运算符

C++ 隐式构造函数是';t使用模板调用用户定义的运算符,c++,templates,C++,Templates,在我的代码中,我实现了Vector3模板,如下所示: template <typename T> struct TVector3{ TVector3(const T& x, const T& y, const T& z); // normal constructor from x,y,z TVector3(const T& val); // construct from a constant value // .. ot

在我的代码中,我实现了Vector3模板,如下所示:

template <typename T>
struct TVector3{
    TVector3(const T& x, const T& y, const T& z);   // normal constructor from x,y,z
    TVector3(const T& val);   // construct from a constant value
    // .. other implementation
    T x, y, z;
};
// and my overload operator+ for TVector3
template <typename T>
const TVector3<T> operator+(const TVector3<T>& lhs, const TVector3<T>& rhs)
{
    return TVector3<T>(lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z);
}
模板
结构TVector3{
TVector3(常数T&x,常数T&y,常数T&z);//来自x,y,z的正规构造函数
TVector3(const T&val);//从常量值构造
//…其他实施
tx,y,z;
};
//还有我的TVector3过载操作员+
样板
const TVector3操作员+(const TVector3和左侧、const TVector3和右侧)
{
返回TVector3(左x+右x,左y+右y,左z+右z);
}
我期待这样的电话:(1,2,3)+1=(2,3,4),所以我这样写:

TVector3<float> v(1, 2, 3);
v + 1.0f;   // error, on operator "+" matches ... operand types are: TVector3<float> + float
tvector3v(1,2,3);
v+1.0f;//运算符“+”匹配时出错。。。操作数类型为:TVector3+浮点
然后我似乎明白了模板推断应该完全匹配参数类型,而不是转换它们,所以我有没有办法告诉编译器将T转换为TVector3?我不想写下面这样的2个重载,因为代码会变得很大:

template <typename T>
const TVector3<T> operator+(const TVector3<T>& lhs, const T& rhs);
template <typename T>
const TVector3<T> operator+(const T& rhs, const TVector3<T>& rhs);
模板
常量TVector3操作员+(常量TVector3和左侧、常量T和右侧);
样板
const TVector3操作员+(const T&rhs、const TVector3&rhs);

谢谢你的帮助

这里的技巧是在实例化类模板时实例化一个实际上不是成员的函数。这可以通过朋友定义(内联朋友)实现。当类模板被实例化时,friend也被实例化,并且作为一个非模板函数被注入到周围的名称空间中(以受限的方式),以便应用转换。(我还将返回值设为非常量,因为我认为这不是您的本意。)有关更多详细信息,请参阅查找“朋友名称注入”、“参数相关查找”以及相关的Barton Nackman技巧

template <typename T>
struct TVector3{
    friend TVector3<T> operator+(const TVector3<T>& lhs, const TVector3<T>& rhs) {
        return TVector3<T>(lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z);
    }
    TVector3(const T& x, const T& y, const T& z);   // normal constructor from x,y,z
    TVector3(const T& val);   // construct from a constant value
    // .. other implementation
    T x, y, z;
};

int
main() {

    TVector3<float> v(1, 2, 3);
    v + 1.0f; // Works.
}
模板
结构TVector3{
friend TVector3操作员+(常数TVector3&lhs、常数TVector3&rhs){
返回TVector3(左x+右x,左y+右y,左z+右z);
}
TVector3(常数T&x,常数T&y,常数T&z);//来自x,y,z的正规构造函数
TVector3(const T&val);//从常量值构造
//…其他实施
tx,y,z;
};
int
main(){
tvector3v(1,2,3);
v+1.0f;//有效。
}
需要注意的一个重要且相关的事情是,模板函数和非模板函数之间存在差异,即使签名在其他方面是相同的

A类模板;
无效f(A);//1.
样板
无效f(A);//2.
样板
甲级{
friend void f(A);//如果T==int,则使1成为朋友,而不是2。
朋友虚空f(A);///使2也成为朋友。
};

这里的技巧是在实例化类模板时实例化一个实际上不是成员的函数。这可以通过朋友定义(内联朋友)实现。当类模板被实例化时,friend也被实例化,并且作为一个非模板函数被注入到周围的名称空间中(以受限的方式),以便应用转换。(我还将返回值设为非常量,因为我认为这不是您的本意。)有关更多详细信息,请参阅查找“朋友名称注入”、“参数相关查找”以及相关的Barton Nackman技巧

template <typename T>
struct TVector3{
    friend TVector3<T> operator+(const TVector3<T>& lhs, const TVector3<T>& rhs) {
        return TVector3<T>(lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z);
    }
    TVector3(const T& x, const T& y, const T& z);   // normal constructor from x,y,z
    TVector3(const T& val);   // construct from a constant value
    // .. other implementation
    T x, y, z;
};

int
main() {

    TVector3<float> v(1, 2, 3);
    v + 1.0f; // Works.
}
模板
结构TVector3{
friend TVector3操作员+(常数TVector3&lhs、常数TVector3&rhs){
返回TVector3(左x+右x,左y+右y,左z+右z);
}
TVector3(常数T&x,常数T&y,常数T&z);//来自x,y,z的正规构造函数
TVector3(const T&val);//从常量值构造
//…其他实施
tx,y,z;
};
int
main(){
tvector3v(1,2,3);
v+1.0f;//有效。
}
需要注意的一个重要且相关的事情是,模板函数和非模板函数之间存在差异,即使签名在其他方面是相同的

A类模板;
无效f(A);//1.
样板
无效f(A);//2.
样板
甲级{
friend void f(A);//如果T==int,则使1成为朋友,而不是2。
朋友虚空f(A);///使2也成为朋友。
};

作为旁注:返回一个
常数TVector3
是。作为旁注:返回一个
常数TVector3
是。它确实有效,但我想知道为什么有效。你能详细解释一下吗?@PhilipZhang:我补充了一些细节。坦率地说,这是C++中的一个特殊情况,非常感谢您的友好解释!它确实有效,但我想知道它为什么有效。你能详细解释一下吗?@PhilipZhang:我补充了一些细节。坦率地说,这是C++中的一个特殊情况,非常感谢您的友好解释!