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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/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++ 模板和implict构造函数的类定义之外的友元声明_C++_Templates_Metaprogramming - Fatal编程技术网

C++ 模板和implict构造函数的类定义之外的友元声明

C++ 模板和implict构造函数的类定义之外的友元声明,c++,templates,metaprogramming,C++,Templates,Metaprogramming,我希望我的重载运算符+适用于混合类型。非模板类没有问题。 为了使它能够与模板类一起工作,我在类内添加了一个朋友操作符+,它就可以工作了 template <typename T> class Wrapper { T _val; public: Wrapper(T val) :_val(val){} T getValue() const { return _val; } friend Wrapper<T> operator+(const W

我希望我的重载运算符+适用于混合类型。非模板类没有问题。 为了使它能够与模板类一起工作,我在类内添加了一个朋友操作符+,它就可以工作了

template <typename T> class Wrapper
{
    T _val;
public:
    Wrapper(T val) :_val(val){}
    T getValue() const { return _val; }

    friend Wrapper<T> operator+(const Wrapper<T>& val1, const Wrapper<T>& val2)
    {
        return Wrapper<T>(val1.getValue() + val2.getValue());
    }
};

int main()
{
    Wrapper<int> v1 = 10; // OK, implicit constructor
    Wrapper<int> v2(20);
    Wrapper<int> result1 = v1 + v2; // OK, both values are of type Wrapper<int>
    Wrapper<int> result2 = v1 + 40; // Ok, casting by implicit constructor works
    return 0;
}
模板类包装器
{
T_val;
公众:
包装(T val):_val(val){}
T getValue()常量{return\u val;}
友元包装运算符+(常量包装和val1、常量包装和val2)
{
返回包装(val1.getValue()+val2.getValue());
}
};
int main()
{
包装器v1=10;//确定,隐式构造函数
包装材料v2(20);
Wrapper result1=v1+v2;//好,两个值都是Wrapper类型
包装器result2=v1+40;//好的,隐式构造函数的强制转换有效
返回0;
}
现在我想将操作符+实现移到类之外,如下所示:

#include <iostream>
#include <string>

template <typename T> class Wrapper;

template <typename T> Wrapper<T> operator+(const Wrapper<T>& val1, const Wrapper<T>& val2);

template <typename T> class Wrapper
{
    T _val;
public:
    Wrapper(T val) :_val(val){}
    T getValue() const { return _val; }

    friend Wrapper<T> operator+ <>(const Wrapper<T>& val1, const Wrapper<T>& val2);
};

// template<class T> Wrapper<T> operator+(const Wrapper<T>&, const Wrapper<T>&)
// template argument deduction/substitution failed
template <typename T> Wrapper<T> operator+(const Wrapper<T>& val1, const Wrapper<T>& val2)
{
    return Wrapper<T>(val1.getValue() + val2.getValue());
}

int main()
{
    Wrapper<int> v1 = 10; // OK, implicit constructor
    Wrapper<int> v2(20);
    Wrapper<int> result1 = v1 + v2; // OK, both values are of type Wrapper<int>

    // note: mismatched types 'const Wrapper<T>' and 'int'
    Wrapper<int> result2 = v1 + 40; // Error
    return 0;

}
#包括
#包括
模板类包装器;
模板包装运算符+(常量包装&val1,常量包装&val2);
模板类包装器
{
T_val;
公众:
包装(T val):_val(val){}
T getValue()常量{return\u val;}
友元包装运算符+(常量包装和val1,常量包装和val2);
};
//模板包装运算符+(常量包装&,常量包装&)
//模板参数推断/替换失败
模板包装运算符+(常量包装和val1、常量包装和val2)
{
返回包装(val1.getValue()+val2.getValue());
}
int main()
{
包装器v1=10;//确定,隐式构造函数
包装材料v2(20);
Wrapper result1=v1+v2;//好,两个值都是Wrapper类型
//注意:不匹配的类型“const Wrapper”和“int”
包装器结果2=v1+40;//错误
返回0;
}
但是它给了我编译错误(将它们粘贴到上面的代码中)。 有可能把它修好吗

(工作)
(不起作用)

制作这种不是模板函数的friend函数有点奇怪。但是,通过将
friend操作符+
设置为模板函数,您可以对其进行一些更改,以使其正常工作:

template <typename T>
class Wrapper
{
    T _val;
public:
    Wrapper(T val) :_val(val){}
    T getValue() const { return _val; }

    template <typename U>
    friend Wrapper<U> operator+(const Wrapper<U>& val1, const Wrapper<U>& val2);
};

template <typename T>
Wrapper<T> operator+(const Wrapper<T>& val1, const Wrapper<T>& val2)
{
    return Wrapper<T>(val1.getValue() + val2.getValue());
}
模板
类包装器
{
T_val;
公众:
包装(T val):_val(val){}
T getValue()常量{return\u val;}
模板
友元包装运算符+(常量包装和val1,常量包装和val2);
};
模板
包装运算符+(常量包装和val1、常量包装和val2)
{
返回包装(val1.getValue()+val2.getValue());
}
这几乎可以按照您的意愿工作,但是隐式转换被禁用,因为这是一个模板函数。不过,将它们重新添加到中很容易:

template <typename T>
Wrapper<T> operator+(const Wrapper<T>& val1, const T& val2)
{
    return Wrapper<T>{ val1.getValue() + val2 };
}

template <typename T>
Wrapper<T> operator+(const T& val1, const Wrapper<T>& val2)
{
    return Wrapper<T>{ val1 + val2.getValue() };
}
模板
包装运算符+(常数包装和值1,常数T和值2)
{
返回包装器{val1.getValue()+val2};
}
模板
包装运算符+(常数T和值1,常数包装和值2)
{
返回包装{val1+val2.getValue()};
}

@justin是的,伙计,谢谢。缺点是编译器不会测试每个可能的模板实例化,以查看它们是否支持您正在寻找的隐式转换。相关: