std::swap()在排序甚至分配期间被许多std容器(例如std::list和std::vector)使用.
但是std实现swap()非常普遍,而且对于自定义类型来说效率很低.
因此,通过std::swap()使用自定义类型特定实现进行重载可以获得效率.但是如何实现它以便std容器使用它?
关于std命名空间使用'using'似乎有不同的看法.
有人说使用' using namespace std',其他人说不要,而是先加上与' std::' 一起使用的std函数,而其他人则说使用这样的东西:
using std::string;
using std::cout;
using std::cin;
using std::endl;
using std::vector;
Run Code Online (Sandbox Code Playgroud)
对于要使用的所有std函数.
各自的优点和缺点是什么?
考虑一个输入迭代器join_iterator:它迭代其他范围的串联.调用++i反复可以多比简单的慢i += n.
尽管如此,大多数C++代码都要求使用任意数量的迭代器,当迭代器不是随机访问时std::advance,它会自动转向调用++i.
(可悲的是,大多数人使用std::advance(i, n)而不是using std::advance; advance(i, n),所以我不能只advance为我的迭代器供应并依赖ADL.)
另一方面,我不能使用+或+=因为输入迭代器不必实现它们.
所以问题是:在以下情况下,我将如何支持这种情况:
实现这样的迭代器?
使用可能具有优化的输入迭代器operator +=?
(注意advance并且+这不是唯一重要的情况 - distance并且-具有相同的问题.)
C++标准禁止在命名空间中声明类型或定义任何内容std,但它允许您为用户定义的类型专门化标准STL模板.
通常,当我想专注std::swap于我自己的自定义模板类型时,我只是这样做:
namespace std
{
template <class T>
void swap(MyType<T>& t1, MyType<T>& t2)
{
t1.swap(t2);
}
}
Run Code Online (Sandbox Code Playgroud)
......这很好.但我不完全确定我的惯常做法是否符合标准.我这样做了吗?
如果我有一些代码,如:
using namespace std;
namespace myNamespace
{
vector<float> sqrt( vector<float> v ) { return v; }
void func()
{
vector<float> myVec = { 1, 2, 3, 4 };
std::cout << sqrt( myVec )[0] << std::endl;
float myFloat = 4.0f;
std::cout << sqrt( myFloat ) << std::endl; // need to use std::sqrt()
}
}
Run Code Online (Sandbox Code Playgroud)
然后它将无法编译,除非我更改标记的行使用std::sqrt.为什么?据我所知,如果我尝试重新定义sqrt(float),myNamespace那么std::如果我想要使用标准库版本,我必须符合条件.编译器似乎试图转换myFloat而不是仅仅使用另一个(std)命名空间中的函数.
我发现解决这个问题的一种方法是sqrt(vector<float>)在std命名空间中定义但是感觉不对,这个问题的答案表明重载std是非法的.可能不是那么回事......
我怎样才能重载sqrt(或任何其他标准库cmath函数),这样我就不必总是限定使用哪一个并根据传递的函数参数选择编译器?
谢谢.
写了我自己的数字类。超载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) c++ ×6
stl ×2
c++-faq ×1
c++11 ×1
c++20 ×1
iterator ×1
name-lookup ×1
namespaces ×1
optimization ×1
performance ×1
standards ×1
swap ×1