【C++雑記】半日ほどstd::functioinのジェネリック版について考えてたけどどう考えても難しい

新年から「できない|難しい」ネタ。世知辛いですね。あけましておめでとうございます

ツイッター見てたらこんなコードが流れてきた

poly_function<void(_1)> f = [](auto x) {};

https://twitter.com/cpp_akira/status/424244741245378560

C++14で追加されたジェネリックダムダ
我が孤高のコンパイラは現在未対応だが多分今世紀中に追加されるはず
わかんない人はこんな関数オブジェクトをイメージしてもらいたい

struct Gen_Lambda
{
	template<class T>
	void operator()(T x)
	{}
};

こんな感じ

で、これの一般化がさっぱりどうしても難しい。半日考えたけど問題点ばかりポンポン浮かぶ

問題点
仮に、実装できたとしよう

poly_function<void(_1,_2)> expr= [](auto lhs,auto rhs){return lhs+rhs;};

わーい、ぱぱ、代入しちゃうぞー!!

expr= [](auto lhs,auto rhs){return lhs-rhs;};

遊んでみる

poly_function<void(_1,_2)> expr= [](auto lhs,auto rhs){return lhs+rhs;};
std::cout<<expr(2,3);
expr= [](auto lhs,auto rhs){return lhs-rhs;};
std::cout<<expr(2,3);

上手くいきそうだ。しかし

poly_function<void(_1,_2)> expr= [](auto lhs,auto rhs){return lhs+rhs;};
std::cout<<expr(std::string("Zip"),std::string("Zap"));
expr= [](auto lhs,auto rhs){return lhs-rhs;};
std::cout<<expr(std::string("Zip"),std::string("Zap"));	//←文字列-文字列?

死。

poly_functionを作るには使う可能性のある関数に使う可能性のある引数の型をすべての適用可能を調べる必要がある
さもないと実行時にコンパイルエラーを起こす。あらやだ楽しい
適用できない場合例外を投げる方法でもあればいいのだがそれはそれで難しい

つまり背理法より実装は難しい。新年からこんな話