今度はconceptを使って戻り値指定のいらないbindっぽいことをしてみる

前回のエントリのコメントで、Callable conceptがあるよと教えてもらったので、
昨日書いたdecltypeに続き、conceptで似たことをしてみることにした。


conceptGCCでは、std::Callableを使おうとすると、まだ実装されてないよ。みたいなメッセージが出てくるので
ソースを見に行ったところ、こんな記述があった。

  // TODO: cannot express Callable, which is variadic, so we settle
  // for Callable0, Callable1, etc.

なので、varadic templateを使ってないバージョンのCallableを使って書いてみると
↓みたいになった

#include <concepts>
#include <iostream>
#include <string>
#include <boost/bind.hpp>

template <typename F,typename Arg1>
requires std::Callable1<F , Arg1 >
F::result_type mybinder(F obj,Arg1 x)
{
	obj(x);
};

struct Functor
{
	void operator()(std::string str){
		std::cout << str << std::endl;
	}
};

int main()
{
	mybinder(Functor(),"Hello");
	return 0;
}

まあただ転送してるだけなのでbindとはほど遠いけど(ファンクタも返さないし)


次に、コンセプトは、エラーメッセージを読みやすくするのも目的の一つだったと思うので、
試しにエラーを吐かせようと一つファンクタを追加

struct InvalidFunctor
{
	typedef bool result_type;//operator()の戻り値とは違う型をtypedef result_typeしてみる
	void operator()(std::string str){
		std::cout << str << std::endl;
	}
};

int main()
{
	mybinder(Functor(),"Hello");
	mybinder(InvalidFunctor(),"Hello");

	return 0;
}

しかし普通に動いた・・・


なんだかよくわからなくなってきたので、とりあえずtypeinfoでresult_typeの型を調べてみると

#include <concepts>
#include <iostream>
#include <string>
#include <boost/bind.hpp>
#include <typeinfo>
#include <cxxabi.h>

char* demangle(const char *demangle) {
    int status;
    return abi::__cxa_demangle(demangle, 0, 0, &status);
}

template <typename F,typename Args>
requires std::Callable<F , Args >
F::result_type mybinder(F obj,Args x)
{
	obj(x);
	std::cout << demangle(typeid(F::result_type).name()) << std::endl;
};

struct Functor
{
	void operator()(std::string str){
		std::cout << str << std::endl;
	}
};

struct InvalidFunctor
{
	typedef bool result_type;
	void operator()(std::string str){
		std::cout << str << std::endl;
		std::cout << demangle(typeid(result_type).name()) << std::endl;
	}
};

int main()
{
	mybinder(Functor(),"Hello");
	mybinder(InvalidFunctor(),"Hello");

	return 0;
}
//出力
//$ ./a.exe
//Hello
//void
//Hello
//bool
//void

こうなった


うーん。
あんまりちゃんとドラフトを読んでないからあれなんだけど、
そういえばtypedefのスコープってどうなってるんだっけ?とかいろいろとよくわからなくなってきたぞ。
もうちょっとちゃんとドラフトなりを読まないとどうにもならない気がする。