我想延长?或者重载?(不太清楚它叫什么)double和其他基本类型使用的sqrt()函数,所以它可以由我自己的类使用。这里称为" myType"。我将代码函数sqrt()为其参数是myType。我希望sqrt()在用于基本类型时保持不变。这样我就可以编写一个涵盖这两种情况的模板。
例如。下面的关键是能够对基本和myType使用bar()。对于myType而言不是foo(),对于基本类型则不是bar()。这可以干净利落吗?提前感谢您的帮助。
#include <math.h>
using namespace std;
class myType
{
public:
myType() {
}
double sqrt()
{
return 4;//just to return something
}
};
template<typename T> bool bar(T in)
{
if (sqrt(in) == 4) {// handels int and all sorts of other types but not my type
return true;
}
return false;
}
template<typename T> bool foo(T in)
{
if (in.sqrt() == 4) { //handles myType
return true;
}
return false;
}
int main() {
double y = 3;
bar(y);//This is great
myType x;
//bar(x);//this is the line I want to write
foo(x);//stuck doing this
}
答案 0 :(得分:4)
首先,存在依赖于参数的查找(ADL,a.k.a.KönigLookup),它在其参数的命名空间中搜索函数foo()
。因此,如果在命名空间my
中定义类,则可以在该命名空间中定义函数sqrt()
,即使在非限定上下文中调用它也会自动找到它。
其次,为了使您的模板功能通用,您需要启用ADL。但是,如果将其与基本类型一起使用,它仍然不会在命名空间std
内查找。因此,请为编译器提供一个提示,可以在函数中使用std::sqrt
。
示例(草图):
namespace my {
struct number;
number sqrt(number const&);
}
template<typename scalar>
scalar
sym_sqrt(scalar const& s) {
using std::sqrt;
if (s < 0) {
return -sqrt(-s);
else
return sqrt(s);
}
int main() {
float m = ...;
std::cout << sym_sqrt(m);
my::number n = ...;
std::cout << sym_sqrt(n);
}
using namespace std;
。这不应该是必要的,特别是您的班级用户不需要。现在摆脱这种习惯!sqrt
为宏的问题。然后升级编译器。sqrt()
被定义为成员函数,这是一个完全不同的野兽。将其保留为与现有版本类似的免费功能。一般来说,不要盲目地把东西放到课堂上。有充分的理由使用普通函数。特别是在数学意义上表示函数的数学函数(没有副作用,没有外部依赖性)实际上很好地放入函数中。std::sqrt()
已针对非基本类型进行了重载,即针对不同的std::complex<T>
类型。if (X) {return true;} else {return false};
可以写得小得多return X;
。答案 1 :(得分:1)
我认为您无法做任何事情让std::sqrt
使用您的用户定义类型(除非可以使用转换运算符将它们转换为基本数据类型)。但是您可以编写自己的函数,默认情况下重定向到std::sqrt
,并将其专门用于您的用户定义类型。然后在代码中使用该函数,而不是std::sqrt
。