BOOST_TYPE_ERASURE_MEMBER では const なメンバ関数が呼び出せない
[追記]
嘘です。
const なメンバ関数も呼び出すことが出きました。
BOOST_TYPE_ERASURE_MEMBER では、オブジェクトが const だった場合に const なメンバ関数が正しく呼び出せません。
どういうことかというとこういうこと。
[ソース]
#include <boost/type_erasure/any.hpp> #include <boost/type_erasure/member.hpp> #include <boost/mpl/vector.hpp> BOOST_TYPE_ERASURE_MEMBER((has_call), call, 0) struct X{ void call() const{ std::cout << "X::call() const" << std::endl; } }; int main(){ namespace te = boost::type_erasure; typedef boost::mpl::vector< ::has_call<void()>, te::copy_constructible<> > concept_type; X x; te::any<concept_type> a1(x); a1.call(); // OK te::any<concept_type> const a2(x); // a2.call(); // NG return 0; }
なので、const なメンバ関数も呼び出したい場合は、BOOST_TYPE_ERASURE_MEMBER を使用するのではなく、直接 const な関数を呼び出す処理を定義しなければいけません。
[ソース]
#include <boost/type_erasure/any.hpp> #include <boost/type_erasure/member.hpp> #include <boost/mpl/vector.hpp> // BOOST_TYPE_ERASURE_MEMBER((has_call), call, 0) template<typename C = boost::type_erasure::_self> struct has_call{ static void apply(C const& cont){ cont.call(); } }; namespace boost{ namespace type_erasure{ template<typename C, typename Base> struct concept_interface< ::has_call<C>, Base, C> : Base{ void call() const{ boost::type_erasure::call(::has_call<C>(), *this); } }; } // namespace type_erasure } // namespace boost struct X{ void call() const{ std::cout << "X::call() const" << std::endl; } }; int main(){ namespace te = boost::type_erasure; typedef boost::mpl::vector< ::has_call<>, te::copy_constructible<> > concept_type; X x; te::any<concept_type> a1(x); a1.call(); // OK te::any<concept_type> const a2(x); a2.call(); // OK return 0; }
[出力]
X::call() const X::call() const