在多参数情况下使用转换构造函数
Using converting constructor in multiple parameter case
我在看这个视频
CppCon 2018:Dan Saks“结交新朋友”please look here
我在这个谈话中,他指的是一个(假设的)有理数 class(有
分子和分母作为私有成员,所有的计算都围绕着
围绕这个。我正在尝试实施本次演讲中提到的任何内容,只是为了
很好地理解模板。
我知道,Dan 提到了一个执行乘法的函数 int*rational
//~ rational.h
template <typename> class rational;
template <typename T> std::ostream& operator<<(std::ostream&, const rational<T> &);
template <typename T> rational<T> operator*(const rational<T>&, const rational<T>&);
template <typename T>
class rational {
friend std::ostream& operator<<<T>(std::ostream&, const rational<T>&);
friend rational<T> operator*<T>(const rational<T>&, const rational<T>&);
public:
rational();
rational(T num);
rational(T num, T den);
rational(const rational &ro);
rational &operator+=(const rational &ro);
rational &operator*=(const rational &ro);
...
...
private:
T num, den;
};
// implements operator*
template <typename T>
rational<T> operator*(const rational<T> &lo, const rational<T> &ro) {
rational<T> result(ro);
result *= lo;
return result;
}
然后,我们有 main
//~ temp.cpp
#include <iostream>
#include "rational.h"
using namespace std;
int main(int argc, char *argv[]) {
rational<int> r1(1,3);
rational<int> r2(5,6);
cout << "r1=" << r1 << ", r2=" << r2 << endl;
rational<int> r3(3);
r3 = 3*r3;
cout << r3 << endl;
return 0;
}
但是,当我构建它时,出现错误:
onkar@TITAN:~/cc/test$ make
g++ -g -Wno-unused-variable -Wno-unused-but-set-variable -std=c++11 -Wall -c test.cpp
test.cpp: In function ‘int main(int, char**)’:
test.cpp:14:8: error: no match for ‘operator*’ (operand types are ‘int’ and ‘rational<int>’)
14 | r3 = 3*r3;
| ~^~~
| | |
| | rational<int>
| int
In file included from test.cpp:2:
rational.h:58:13: note: candidate: ‘template<class T> rational<T> operator*(const rational<T>&, const rational<T>&)’
58 | rational<T> operator*(const rational<T> &lo, const rational<T> &ro) {
| ^~~~~~~~
rational.h:58:13: note: template argument deduction/substitution failed:
test.cpp:14:9: note: mismatched types ‘const rational<T>’ and ‘int’
14 | r3 = 3*r3;
| ^~
make: *** [Makefile:2: test] Error 1
onkar@TITAN:~/cc/test$
现在,我明白了这个错误(转换构造函数接受单个参数和所有参数)
但问题是:
如何确保 r3 = 3*r3;
正常工作(而且我不必调用(看起来很奇怪)r3 = rational<int>(3)*r3
反正我总能做到。
template argument deduction 中不考虑隐式转换。给定 3*r3
,基于第一个函数参数(即 3
)的 T
的模板参数推导失败;不考虑从 int
到 rational<int>
的隐式转换。
Type deduction does not consider implicit conversions (other than type adjustments listed above): that's the job for overload resolution, which happens later.
您可以将 operator*
更改为非模板,它不会出现此类问题,并且隐式转换会按您的预期工作。
template <typename> class rational;
template <typename T> std::ostream& operator<<(std::ostream&, const rational<T> &);
template <typename T>
class rational {
friend std::ostream& operator<<<T>(std::ostream&, const rational<T>&);
friend rational<T> operator*(const rational<T> &lo, const rational<T> &ro) {
rational<T> result(ro);
result *= lo;
return result;
}
public:
rational();
rational(T num);
rational(T num, T den);
rational(const rational &ro);
rational &operator+=(const rational &ro);
rational &operator*=(const rational &ro);
...
...
private:
T num, den;
};
我在看这个视频 CppCon 2018:Dan Saks“结交新朋友”please look here
我在这个谈话中,他指的是一个(假设的)有理数 class(有 分子和分母作为私有成员,所有的计算都围绕着 围绕这个。我正在尝试实施本次演讲中提到的任何内容,只是为了 很好地理解模板。
我知道,Dan 提到了一个执行乘法的函数 int*rational
//~ rational.h
template <typename> class rational;
template <typename T> std::ostream& operator<<(std::ostream&, const rational<T> &);
template <typename T> rational<T> operator*(const rational<T>&, const rational<T>&);
template <typename T>
class rational {
friend std::ostream& operator<<<T>(std::ostream&, const rational<T>&);
friend rational<T> operator*<T>(const rational<T>&, const rational<T>&);
public:
rational();
rational(T num);
rational(T num, T den);
rational(const rational &ro);
rational &operator+=(const rational &ro);
rational &operator*=(const rational &ro);
...
...
private:
T num, den;
};
// implements operator*
template <typename T>
rational<T> operator*(const rational<T> &lo, const rational<T> &ro) {
rational<T> result(ro);
result *= lo;
return result;
}
然后,我们有 main
//~ temp.cpp
#include <iostream>
#include "rational.h"
using namespace std;
int main(int argc, char *argv[]) {
rational<int> r1(1,3);
rational<int> r2(5,6);
cout << "r1=" << r1 << ", r2=" << r2 << endl;
rational<int> r3(3);
r3 = 3*r3;
cout << r3 << endl;
return 0;
}
但是,当我构建它时,出现错误:
onkar@TITAN:~/cc/test$ make
g++ -g -Wno-unused-variable -Wno-unused-but-set-variable -std=c++11 -Wall -c test.cpp
test.cpp: In function ‘int main(int, char**)’:
test.cpp:14:8: error: no match for ‘operator*’ (operand types are ‘int’ and ‘rational<int>’)
14 | r3 = 3*r3;
| ~^~~
| | |
| | rational<int>
| int
In file included from test.cpp:2:
rational.h:58:13: note: candidate: ‘template<class T> rational<T> operator*(const rational<T>&, const rational<T>&)’
58 | rational<T> operator*(const rational<T> &lo, const rational<T> &ro) {
| ^~~~~~~~
rational.h:58:13: note: template argument deduction/substitution failed:
test.cpp:14:9: note: mismatched types ‘const rational<T>’ and ‘int’
14 | r3 = 3*r3;
| ^~
make: *** [Makefile:2: test] Error 1
onkar@TITAN:~/cc/test$
现在,我明白了这个错误(转换构造函数接受单个参数和所有参数) 但问题是:
如何确保 r3 = 3*r3;
正常工作(而且我不必调用(看起来很奇怪)r3 = rational<int>(3)*r3
反正我总能做到。
template argument deduction 中不考虑隐式转换。给定 3*r3
,基于第一个函数参数(即 3
)的 T
的模板参数推导失败;不考虑从 int
到 rational<int>
的隐式转换。
Type deduction does not consider implicit conversions (other than type adjustments listed above): that's the job for overload resolution, which happens later.
您可以将 operator*
更改为非模板,它不会出现此类问题,并且隐式转换会按您的预期工作。
template <typename> class rational;
template <typename T> std::ostream& operator<<(std::ostream&, const rational<T> &);
template <typename T>
class rational {
friend std::ostream& operator<<<T>(std::ostream&, const rational<T>&);
friend rational<T> operator*(const rational<T> &lo, const rational<T> &ro) {
rational<T> result(ro);
result *= lo;
return result;
}
public:
rational();
rational(T num);
rational(T num, T den);
rational(const rational &ro);
rational &operator+=(const rational &ro);
rational &operator*=(const rational &ro);
...
...
private:
T num, den;
};