티스토리 뷰



// Coded with Dev-C++ IDE

#include <iostream>
#include <algorithm>
using namespace std;

namespace DW {
   
    template <typename IntegerT>
    class Glass {
    public:
        Glass() { cout<< "ctor.." << endl; }
        Glass(IntegerT x, IntegerT y)
        {
            cout<< "ctor.." << endl;
            this->x = x;
            this->y = y;       
        }
       
       
        void swap(Glass<IntegerT>& g) // This function should not raise any exception.
        {
            cout << "Particular implementation of swap for Glass class.." << endl;           
            // , but we use here very simple code..(not specific..)           
            Glass<IntegerT> temp = g;
            g = *this;
            *this = g;          
        }
       
        // We can use non-friend operators,
        // but friend ver. are used here for convenience.
       
        template <IntegerT>
        friend ostream& operator<<(std::ostream& os, const Glass<IntegerT>& g);
       
        template <IntegerT>
        friend Glass<IntegerT>& operator+(const Glass<IntegerT>& lhs,
                                          const Glass<IntegerT>& rhs);
        template <IntegerT>
        friend bool operator==(const Glass<IntegerT>& lhs,
                               const Glass<IntegerT>& rhs);
       
        int x;
        int y;
           
    };
   
    template <typename IntegerT>
    Glass<IntegerT> operator+(const Glass<IntegerT>& lhs,
                              const Glass<IntegerT>& rhs)
    {
        Glass<IntegerT> glass(lhs.x+rhs.x, lhs.y+rhs.y);
        return glass;
    }
   
    template <typename IntegerT>
    ostream& operator<<(std::ostream& os, const Glass<IntegerT>& g)
    {
        os << "(x, y) = (" << g.x << ", " << g.y << ")";
        return os;       
    }
   
    template <typename IntegerT>
    bool operator==(const Glass<IntegerT>& lhs,
                    const Glass<IntegerT>& rhs)
    {
        return lhs.x == rhs.x && lhs.y == rhs.y;
    }
   
   
    template <typename IntegerT>
    void swap(Glass<IntegerT>& lhs, Glass<IntegerT>& rhs)
    {
        cout << "This swap() is not std ver." << endl;
        lhs.swap(rhs);       
    }

   
   
} // end of namespace DW


using namespace DW;

int main()
{
    Glass<int> g1(1, 3);
    Glass<int> g2(1, 4);
   
    cout << g1 << endl;
    cout << g2 << endl;
   
    using std::swap;
    swap(g1, g2);

    cout << g1 << endl;
    cout << g2 << endl;
   
   
    system("pause");
    return 0;
}






위 코드에서 파란색 부분의 코드를 주석처리하고 실행하면 다음과 같은 결과를 얻을 수 있다.
std::swap이 실행된 것이다.
ctor..
ctor..
(x, y) = (1, 3)
(x, y) = (1, 4)
(x, y) = (1, 4)
(x, y) = (1, 3)
계속하려면 아무 키나 누르십시오 . . .



주석을 해제하면 Glass<IntegerT> 버전의 swap이 호출된다.
이와 같은 C++의 동작을 인자 기반 탐색(argument-dependent lookup) 또는 쾨니그 탐색(Koenig lookup)이라고 한다 (참고 : Effective C++ 3판, 곽용재 옮김). 동일한 이름을 갖는 여러 함수가 호출 후보로 떠오를 때, 클래스와 동일한 네임스페이스에 존재하는 특수화 버전의 함수에게 호출 우선 순위를 주는 규칙이다. 코드 실행 결과는 다음과 같다.

ctor..
ctor..
(x, y) = (1, 3)
(x, y) = (1, 4)
(x, y) = (1, 4)
(x, y) = (1, 3)
계속하려면 아무 키나 누르십시오 . . .

댓글