Programing

내 수업에 스왑 기능을 제공하는 방법은 무엇입니까?

lottogame 2020. 10. 6. 07:45
반응형

내 수업에 스왑 기능을 제공하는 방법은 무엇입니까?


swapSTL 알고리즘 을 활성화하는 올바른 방법은 무엇입니까 ?

1) 회원 swap. 합니까는 std::swap멤버를 사용하는 SFINAE의 트릭을 사용합니다 swap.

2) swap동일한 네임 스페이스에서 독립형 .

3) std::swap.

4) 위의 모든 것.

감사합니다.

편집 : 내 질문을 명확하게 말하지 않은 것 같습니다. 기본적으로 템플릿 클래스가 있으며 해당 클래스에 대해 작성한 (효율적인) 스왑 방법을 사용하려면 STL 알고리즘이 필요합니다.


1) 적절한 인 사용swap. "라이브러리"코드를 작성하고에서 ADL (인수 종속 조회)을 활성화하려는 경우 이렇게 작성합니다 swap. 또한 이것은 SFINAE와 관련이 없습니다.

// some algorithm in your code
template<class T>
void foo(T& lhs, T& rhs){
  using std::swap; // enable 'std::swap' to be found
                   // if no other 'swap' is found through ADL
  // some code ...
  swap(lhs, rhs); // unqualified call, uses ADL and finds a fitting 'swap'
                  // or falls back on 'std::swap'
  // more code ...
}

2) swap수업에 함수 를 제공하는 적절한 방법 입니다.

namespace Foo{

class Bar{}; // dummy

void swap(Bar& lhs, Bar& rhs){
  // ...
}

}

경우 swap1과 같이 현재)를 사용, 함수가 발견됩니다. 또한 꼭 필요한 경우 해당 함수를 친구로 만들거나 swapfree 함수에 의해 호출되는 멤버 제공 할 수 있습니다.

// version 1
class Bar{
public:
  friend void swap(Bar& lhs, Bar& rhs){
    // ....
  }
};

// version 2
class Bar{
public:
  void swap(Bar& other){
    // ...
  }
};

void swap(Bar& lhs, Bar& rhs){
  lhs.swap(rhs);
}

3) 명시적인 전문화를 의미합니다. Partial은 여전히 ​​다른 것이며 함수에 대해서도 가능하지 않으며 구조체 / 클래스 만 가능합니다. 당신은 전문 수 없기 때문에 이와 같이, std::swap템플릿 클래스, 당신은 네임 스페이스에 무료 기능을 제공 할 수 있습니다. 내가 그렇게 말할 수 있다면 나쁜 것은 아닙니다. 이제 명시적인 전문화도 가능하지만 일반적으로 함수 템플릿을 전문화하고 싶지는 않습니다 .

namespace std
{  // only allowed to extend namespace std with specializations

template<> // specialization
void swap<Bar>(Bar& lhs, Bar& rhs){
  // ...
}

}

4) 아니오, 1)은 2) 및 3)과 구별됩니다. 또한 2)와 3)을 모두 가지고 있으면 더 잘 맞기 때문에 항상 2)가 선택됩니다.


To answer the EDIT, where the classes may be template classes, you don't need specialization at all. consider a class like this:

template <class T>
struct vec3
{
    T x,y,z;
};

you may define classes such as:

vec3<float> a;
vec3<double> b;
vec3<int> c;

if you want to be able to create one function to implement all 3 swaps (not that this example class warrants it) you do just like Xeo said in (2)... without specialization but just make a regular template function:

template <class T>
void swap(vec3<T> &a, vec3<T> &b)
{
    using std::swap;
    swap(a.x,b.x);
    swap(a.y,b.y);
    swap(a.z,b.z);
}

The swap template function should be located in the same namespace as the class you're trying to swap. the following method will find and use that swap even though you're not referencing that namespace using ADL:

using std::swap;
swap(a,b);

It seems that (2) (free standing swap in the same namespace where the user-defined class is declared) is the only allowed way to provide swap for a user-defined class, because adding declarations to namespace std is generally an undefined behavior. Extending the namespace std (cppreference.com):

It is undefined behavior to add declarations or definitions to namespace std or to any namespace nested within std, with a few exceptions noted below

And swap is not denoted as one of those exceptions. So adding your own swap overload to the std namespace is an undefined behavior.

It's also said that the standard library uses an unqualified call to the swap function in order to call user-defined swap for a user class if such user-defined swap is provided.

Swappable (cppreference.com):

Many standard library functions (for example, many algorithms) expect their arguments to satisfy Swappable, which means that any time the standard library performs a swap, it uses the equivalent of using std::swap; swap(t, u);.

swap (www.cplusplus.com):

Many components of the standard library (within std) call swap in an unqualified manner to allow custom overloads for non-fundamental types to be called instead of this generic version: Custom overloads of swap declared in the same namespace as the type for which they are provided get selected through argument-dependent lookup over this generic version.

But note that directly using the std::swap function for a user-defined class calls the generic version of std::swap instead of the user-defined swap:

my::object a, b;
std::swap(a, b); // calls std::swap, not my::swap

So it is recommended to call the swap function in user code in the same way as it is done in the standard library:

my::object a, b;
using std::swap;
swap(a, b); // calls my::swap if it is defined, or std::swap if it is not.

참고URL : https://stackoverflow.com/questions/6380862/how-to-provide-a-swap-function-for-my-class

반응형