2015-09-24 3 views
0

У меня есть код, как это:станд :: своп не вызывает мое выполнение пользовательских подкачки C++ 11

#include <utility> 
#include <iostream> 

struct thing { 
    void swap(thing & other){ 
     std::cout << "swap method" << std::endl; 
    } 
}; 

void swap(thing & a, thing & b) { 
    std::cout << "swap function" << std::endl; 

    a.swap(b); 
} 

struct another{ 
    thing a; 
}; 


int main(int argc, char** argv){ 
    another a, b; 

    std::swap(a, b); 
} 

Если выполняется, он ничего не печатает - например, он не использует мой «пользовательский» swap.

Я читал, что НЕ должен быть std :: swap специализация.

Нужно ли выполнять обычную своп для класса another, или мне что-то не хватает?

+4

Как вы ожидаете, что ваш пользовательский 'swap()' будет вызван? Вы сами вызываете 'std :: swap()' в конце концов! – CinCout

+0

хорошо, это именно то, что я точно не понял. , так что мне нужна специальность шаблона в пространстве имен std? – Nick

ответ

6

std::swap не назовёт ваш swap. То, что вы должны делать (в родовом коде), чтобы позволить разрешение перегрузки выбрать самостоятельно:

namespace stuff 
{ 
    struct foo { void swap(foo& other); }; 

    swap(foo& lhs, foo& rhs) { lhs.swap(rhs); } 
} 

int main() 
{ 
    foo a, b; 
    int i = 0; 
    int j = 42; 

    using std::swap; 

    swap(i, j); // calls std::swap 
    swap(a, b); // calls stuff::swap(stuff::foo&, stuff::foo&) via ADL 
} 
+0

так что 'swap' больше подходит для утиного набора? и мне нужно добавить специализацию шаблона или сделать еще одну функцию подкачки для класса «другой»? – Nick

+1

@Nick Вы можете специализироваться на шаблоне 'std :: swap' для вашего типа, но обычной практикой является определение ваших типов и функций в вашем собственном пространстве имен, а затем использование трюка, показанного выше (' using std :: swap' в область, в которую вы хотите выполнить обмен.) – juanchopanza

+2

@Nick: «duck typing» подразумевает параметрический полиморфизм (шаблоны, макросы), тогда как для создания типов «swap» для каждого типа является явно ad-hoc-полиморфизмом. –

0

Вы называете явно для std::swap - нет никаких причин, ваш пользовательский метод должен быть вызван.

Однако, если вы это измените - обязательно измените интерфейс метода - в этой форме будут возникать ошибки компиляции.

1

Ваш swap ожидает thing. Это то, что вы хотите?

int main(int argc, char** argv){ 
    another a, b; 

    using std::swap; // let the compiler decide which swap to use 

    swap(a.a, b.a); // calls swap(thing & a, thing & b) and thing.swap 
} 
+0

Откуда берется '.a'? – nwp

+3

@nwp '.a' имеет тип' вещь' – CinCout