这个成语是什么,什么时候应该使用?它解决了哪些问题?当使用C++ 11时,成语是否会改变?
虽然在许多地方已经提到过,但我们没有任何单一的"它是什么"问题和答案,所以在这里.以下是前面提到的地方的部分列表:
c++ c++-faq copy-constructor assignment-operator copy-and-swap
启用swapSTL算法的正确方法是什么?
1)会员swap.是否std::swap使用SFINAE技巧来使用该成员swap.
2)自由站立swap在同一名称空间中.
3)部分专业化std::swap.
4)以上所有.
谢谢.
编辑:看起来我没有清楚地说出我的问题.基本上,我有一个模板类,我需要STL algos来使用我为该类编写的(高效)交换方法.
考虑以下代码:
#include <utility>
namespace ns
{
struct foo
{
foo() : i(0) {}
int i;
private:
foo(const foo&); // not defined,
foo& operator=(const foo&); // non-copyable
};
void swap(foo& lhs, foo& rhs)
{
std::swap(lhs.i, rhs.i);
}
}
template <typename T>
void do_swap(T& lhs, T& rhs); // implementation to be determined
int main()
{
ns::foo a, b;
do_swap(a, b);
}
Run Code Online (Sandbox Code Playgroud)
在C++ 03中,这种实现do_swap将被视为"已损坏":
template <typename T>
void do_swap(T& lhs, T& rhs)
{
std::swap(lhs, rhs);
}
Run Code Online (Sandbox Code Playgroud)
通过明确指定std::,它禁止ns::swap …
在通用函数中,我使用以下习语,
template<class It1, class It2>
void do_something(It1 first, It1 second, It2 d_first){
... other stuff here...
using std::copy;
copy(first, second, d_first);
}
Run Code Online (Sandbox Code Playgroud)
do_something是一个通用函数,不应该知道任何其他任何库(可能除外std::).
现在假设我的命名空间中有几个迭代器N.
namespace N{
struct itA{using trait = void;};
struct itB{using trait = void;};
struct itC{using trait = void;};
}
Run Code Online (Sandbox Code Playgroud)
我想在这个命名空间中重载这些迭代器的副本.我当然会这样做:
namespace N{
template<class SomeN1, class SomeN2>
SomeN2 copy(SomeN1 first, SomeN1 last, SomeN2 d_first){
std::cout << "here" << std::endl;
}
}
Run Code Online (Sandbox Code Playgroud)
然而,当我打电话do_something用N::A,N::B或N::C争论,我得到"暧昧通话复制"即使这些都在同一个命名空间N::copy.
有没有办法 …
嗨!
我使用了以下C宏,但在C++中它无法自动转换void*为type*.
#define MALLOC_SAFE(var, size) { \
var = malloc(size); \
if (!var) goto error; \
}
Run Code Online (Sandbox Code Playgroud)
我知道,我可以这样做:
#define MALLOC_SAFE_CPP(var, type, size) { \
var = (type)malloc(size); \
if (!var) goto error; \
}
Run Code Online (Sandbox Code Playgroud)
但我不想重写大部分代码,MALLOC_SAFE使用的地方.
有没有办法在没有给宏的类型的情况下这样做?也许一些MSVC 2005 #pragma/__declspec/其他?
ps:我不能使用C编译器,因为我的代码是大项目的一部分(数百个模块之一).现在它是在C++上.我知道,我可以单独构建我的代码.但这是旧代码,我只是想快速移植它.
问题是关于void*cast;)如果不可能,我只需用MACRO_SAFE_CPP替换MACRO_SAFE
谢谢!
这个问题的灵感来自于这个问题.考虑一下代码:
namespace ns {
template <typename T>
void swap(T& a, T& b) {
using namespace std;
swap(a, b);
}
}
Run Code Online (Sandbox Code Playgroud)
在使用GCC进行一些测试后,我发现swap(a, b);解析为
1)std::swap如果T已经过载std::swap(例如,标准容器类型)
2)ns::swap否则,导致无限递归.
因此,似乎编译器将首先尝试在命名空间中找到匹配项ns.如果找到匹配项,则搜索结束.但是当ADL进入时并非如此,在这种情况下,std::swap无论如何都会找到.解决过程似乎很复杂.
我想知道swap(a, b)在上面的上下文中解析函数调用过程中发生了什么的细节.可以参考该标准.
c++ function-calls language-lawyer overload-resolution argument-dependent-lookup