C++でDuck Typing

>Duck Typing
調べてみたけどさっぱりだー
クラスAとBがあって、それぞれに継承関係がなかったとしても、同じメソッドを持っていれば同じように扱うことができる…ってことかなぁ…むずかしぃ

それで間違ってないです。難しいっていうのは理屈では理解できるけどでも、あひるがどうのこうの言われても実感がわかないとってことだと思うので、簡単なサンプル。

#include <iostream>
#include <vector>
#include <list>
#include <string>
#include <iterator>
#include <algorithm>

template<typename Source, typename Destination>
void copy_container(const Source& src, Destination& dest)
{
    typedef typename Source::const_iterator input_iterator;
    dest.clear();

    for (input_iterator it = src.begin(); it != src.end(); it++) {
        dest.push_back(*it);
    }
}

int main(int argc, char **argv)
{
    std::vector<char> v;
    std::list<char> l;
    std::string s;
    for (char c = 'a'; c <= 'z'; c++) {
        v.push_back(c);
    }

    copy_container(v, l);
    copy_container(l, s);
    std::copy(l.begin(), l.end(), std::ostream_iterator<char>(std::cout));
    std::cout << std::endl;
    std::cout << s << std::endl;

    return 0;
}

src は begin() と end() で iterator を返せばいいし、dest は push_back をサポートしておけば何でもよいと。別にSTLのコンテナクラスである必要もない。
あと pointer も iterator のサポートする演算(逆参照('*') とかインクリメント('++')) をサポートしているので、 std::copy や std::sort などの iterator を受け取る関数にそのまま渡せたりして、こういうのも Duck Typing と呼べるかも知れない。下の様な感じ。

std::vector<int> v;

// do something

size_t size = v.size();
int* a = new int[size];
std::copy(v.begin(), v.end(), a);

// do something

std::copy(a, a + size, std::ostream_iterator<int>(std::cout, "\n"));
delete[] a;

ってことでどうでしょうか。>id:noya さん。