std::swap()在排序甚至分配期间被许多std容器(例如std::list和std::vector)使用.
但是std实现swap()非常普遍,而且对于自定义类型来说效率很低.
因此,通过std::swap()使用自定义类型特定实现进行重载可以获得效率.但是如何实现它以便std容器使用它?
我今天读到一些有趣的内容,说用户提供的类型(作为模板参数提供)调用swap的"标准"方式是......
using std::swap;
swap(something, soemthingelse);
Run Code Online (Sandbox Code Playgroud)
这样做的原因是使用的参数依赖查找要么使用一个swap在用户的命名空间或函数swap的std命名空间.这为我提出了一个感兴趣的问题.当我超载std::swap了我的课之一,我实际上已被定义它的std命名空间... namespace std { void swap(/*...*/){/*...*/} }.这种做法错了吗?我应该定义自己的swaps std或我自己的命名空间(以及为什么)?
可能重复:
如何为我的班级提供交换功能?
每次我认为我理解它,我都会看到让我感到困惑的事情.
如果您想swap为自己的课程提供实施,您会怎么做?
可能性列表如下:
在std命名空间中定义一个(带两个参数),在下面调用#3
(有人说这是正确的;有些人说非法)
在类中定义一个静态方法,接受两个参数交换
(对我来说比#4更有意义,但我不明白为什么没有人这样做),它会swap根据需要调用任何基类
定义一个实例方法的类的内部,采取一个其他参数与交换,它调用任何基础类swapS作为必要
定义一个实例方法的类中,以2个其它参数来交换,也这里,任何基础类这就要求swapS作为必要
还有别的
我自己的理解是,我需要#5,#3,凡来电将被调用swap一样using std::swap; swap(a, b);,但似乎没有人认为联合是真正困惑我的事实.我真的根本不理解#4,因为实际上每个人似乎都在使用实例成员,而实际操作是静态的.我无法分辨我的理解是错误的还是我在查看时看到的一堆答案.
什么是正确的方法?
我会简短地介绍一下代码示例:
class myClass
{
public:
myClass();
int a;
int b;
int c;
}
// In the myClass.cpp or whatever
myClass::myClass( )
{
a = 0;
b = 0;
c = 0;
}
Run Code Online (Sandbox Code Playgroud)
好的.如果我知道有一个myClass的实例并将一些随机垃圾设置为a,b和c.
我想出了这样的方式:
myClass emptyInstance;
myUsedInstance = emptyInstance; // Ewww.. code smell?
Run Code Online (Sandbox Code Playgroud)
要么..
myUsedInstance.a = 0; myUsedInstance.c = 0; myUsedInstance.c = 0;
Run Code Online (Sandbox Code Playgroud)
我读过C++ Primer,它说功能模板专业化是一个高级主题,但我完全迷失了.任何人都可以提供一个例子,为什么功能模板专业化是重要和必要的?
为什么功能模板不支持类模板的部分专业化?底层逻辑是什么?
我正在编写一个库来处理二维矩阵代数,使用矩阵内数据类型的模板,以便拥有最大的自由度并基本上处理我想要的任何类型数据的矩阵。
我想知道是否有某种方法可以重载该abs() 函数,以便将矩阵的行列式写为abs(M);,或者我是否必须使用另一个名称。我唯一关心的是矩阵的行列式与其绝对值相关(如标准符号所示),因此在我看来,重载绝对值函数以返回行列式是有意义的。
我已经尝试将其设为类方法,并使用 来调用它m.abs();,显然这工作得很好......但我希望函数位于类之外,并获取矩阵作为参数,就像函数一样int abs(int n); 。因此,我尝试重载该函数,但这给了我一些问题,因为该abs(n);函数需要一些整数或长整型值作为参数,当然不是用户定义的矩阵。我也尝试将其设为班级的友元方法,但似乎没有帮助。期待您的建议。
写了我自己的数字类。超载std::numeric_limit::max()就好。然而,我正在尝试超载std::abs()但编译器不喜欢我的尝试。我试过这个:
namespace std \n{\n template<uint8_t T> \n MyType<T> abs(const MyType<T>& mt)\n {\n MyType<T> copy = mt;\n copy.val = std::abs(md.val);\n return copy;\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n但是,编译器没有发现重载:
\nerror: no matching function for call to \xe2\x80\x98abs(const MyType<10>&)\xe2\x80\x99\n/usr/include/c++/11/bits/std_abs.h:56:3: note: candidate: \xe2\x80\x98long int std::abs(long int)\xe2\x80\x99\n 56 | abs(long __i) { return __builtin_labs(__i); }\n | ^~~\n/usr/include/c++/11/bits/std_abs.h:56:12: note: no known conversion for argument 1 from \xe2\x80\x98const MyType<10>\xe2\x80\x99 to \xe2\x80\x98long int\xe2\x80\x99\n 56 | abs(long __i) { return __builtin_labs(__i); }\n | ~~~~~^~~\n/usr/include/c++/11/bits/std_abs.h:61:3: note: candidate: …Run Code Online (Sandbox Code Playgroud)