関数のデフォルト引数に lambda expressions を渡す

ふと出来るのかと思って試してみました。

[ソース]

#include <type_traits>
#include <iostream>

template<typename T>
struct identity{
    using type = T;
};

template<
    typename T
>
void
disp(
    std::initializer_list<T> list,
    typename identity<void(*)(T)>::type func = [](T n){ std::cout << n << std::endl; }
){
    for(auto&& n : list){
        func(n);
    }
}


int
main(){
    disp({1, 2, 3});

    disp({0.1f, 0.2f, 0.3f}, [](float f){
        std::cout << "value:" << f << std::endl;
    });

    return 0;
}

[出力]

1
2
3
value:0.1
value:0.2
value:0.3

一応、これだと問題なさそうかな。


元々は下記のようにテンプレート引数でも受け取るような書き方にしていたんですが、これだと gcc 4.7 でエラーになってしまいました。

template<
    typename T,
    typename Func = void(*)(T)
>
void
disp(std::initializer_list<T> list, Func func = [](T n){ std::cout << n << std::endl; }){
    for(auto&& n : list){
        func(n);
    }
}

disp({1, 2, 3});

struct disper{
    template<typename T>
    void operator ()(T&& n) const{
        std::cout << n << ", ";
    }
};
disp({std::string("homu"), std::string("mado"), std::string("mami")}, disper{});

clang3.1 では問題がなかったんですが…うむむ…。

[コンパイラ]

  • g++ (GCC) 4.7.0 20120218 (experimental)
  • clang++ (LLVM) 3.1 20120226(trunk)