2017-01-20 7 views
1

:私はDerivedオブジェクト上のADLスワップを使用しようとすると使用ADLスワップ

#include <iostream> 
#include <utility> 

struct Base { 
    friend void swap(Base&, Base&) 
    { 
     std::cout << "base swap\n"; 
    } 
}; 

struct Derived : Base {}; 

int main() 
{ 
    Derived d1, d2; 

    using std::swap; 
    swap(d1, d2); 
} 

Baseのためのスワップ機能が起動されません。代わりに、std::swapが使用されます。 Derivedのための別のADLスワップを作成する必要がありますか?この状況のベストプラクティスは何ですか?

答えて

2

ベース内のswapが考慮されますが、std::swapは、ベースに変換する必要がないため、より良い一致とみなされます。

ここ

はそれで刺しです:悲しいこと

struct Base { 
    template<class T, 
    std::enable_if_t<std::is_base_of<Base, T>{}, int> =0 
    > 
    friend void swap(T&, T&) { 
    std::cout << "base swap\n"; 
    } 
}; 

std::swapはないとして、それがまったく同じ過負荷「強さ」を持っていると我々は曖昧さを得るように、これは、動作しません。

live example

私は、その落とし穴に遭遇しないようなスワップインベースを作成する方法を知らない。

おそらく概念は、私たちが友人の交換をstd::swapより「専門化」するために必要な力を与えるでしょう。

1

ヤクは、std::swapよりも特殊化された機能を行う方法がないと述べています。しかし、私たちは自分自身を作ることができます。

#include <iostream> 
#include <utility> 
#include <type_traits> 

struct Base { 
    template< 
     class T, 
     std::enable_if_t<std::is_base_of<Base, T>{}, int> = 0 
    > 
    friend void adl_swap(T& lhs, T& rhs) { 
     std::cout << "base swap\n"; 
    } 
}; 

struct Derived : Base {}; 


template< 
    class T, 
    std::enable_if_t<!std::is_base_of<Base, T>{}, int> = 0 
> 
void adl_swap(T& lhs, T& rhs) { 
    std::cout << "std::swap\n"; 
    using std::swap; 
    swap(lhs, rhs); 
} 


int main() { 
    Derived d1, d2; 
    adl_swap(d1, d2); // output : base swap 

    int a{1}, b{2}; 
    adl_swap(a,b); // output : std::swap 
} 
関連する問題