[Type Erasure] Ambiguous call with vs 2015 community

Dear all, I try to use type erasure on the free function foo. However, VS 2015 failed to compile the following code, which is OK with GCC and CLang. ========================================================= #include <boost/type_erasure/any.hpp> #include <boost/type_erasure/free.hpp> #include <typeindex> std::type_index foo(int); BOOST_TYPE_ERASURE_FREE((HasGetField), foo, 1) using Type = boost::type_erasure::any< HasGetField<std::type_index(boost::type_erasure::_self const&)>, boost::type_erasure::_self const&
;
std::type_index foo(int) { return typeid(int); } int main() { Type x{ 1 }; foo(x); return 0; } ========================================================= Source.cpp C:\Program Files\Microsoft Visual Studio 14.0\VC\INCLUDE\xlocale(341): warning C4530: C++ exception handler used, but unwind semantics are not enabled. Specify /EHsc Source.cpp(20): error C2668: 'boost::type_erasure::injectHasGetField<R (const boost::type_erasure::_self &),Base,boost::type_erasure::index_list<0>>::foo': ambiguous call to overloaded function with [ R=std::type_index, Base=boost::type_erasure::any_base<boost::type_erasure::any<HasGetField<std::type_index (const boost::type_erasure::_self &)>,boost::type_erasure::_self &&>> ] Source.cpp(7): note: could be 'std::type_index boost::type_erasure::injectHasGetField<R (const boost::type_erasure::_self &),Base,boost::type_erasure::index_list<0>>::foo(eval_if_c<0,boost::type_erasure::detail::maybe_const_this_param<const boost::type_erasure::_self &,Base>,boost::type_erasure::as_param<Base,const boost::type_erasure::_self &>>::type)' [found using argument-dependent lookup] with [ R=std::type_index, Base=boost::type_erasure::any_base<boost::type_erasure::any<HasGetField<std::type_index (const boost::type_erasure::_self &)>,boost::type_erasure::_self &&>> ] Source.cpp(7): note: or 'std::type_index boost::type_erasure::injectHasGetField<R (const boost::type_erasure::_self &),Base,boost::type_erasure::index_list<0>>::foo(eval_if_c<0,boost::type_erasure::detail::maybe_const_this_param<const boost::type_erasure::_self &,Base>,boost::type_erasure::as_param<Base,const boost::type_erasure::_self &>>::type)' [found using argument-dependent lookup] with [ R=std::type_index, Base=boost::type_erasure::any_base<boost::type_erasure::any<HasGetField<std::type_index (const boost::type_erasure::_self &)>,boost::type_erasure::_self &>> ] Source.cpp(7): note: or 'std::type_index boost::type_erasure::injectHasGetField<R (const boost::type_erasure::_self &),Base,boost::type_erasure::index_list<0>>::foo(eval_if_c<0,boost::type_erasure::detail::maybe_const_this_param<const boost::type_erasure::_self &,Base>,boost::type_erasure::as_param<Base,const boost::type_erasure::_self &>>::type)' [found using argument-dependent lookup] with [ R=std::type_index, Base=boost::type_erasure::any_base<boost::type_erasure::any<HasGetField<std::type_index (const boost::type_erasure::_self &)>,boost::type_erasure::_self>> ] Source.cpp(7): note: or 'std::type_index boost::type_erasure::injectHasGetField<R (const boost::type_erasure::_self &),Base,boost::type_erasure::index_list<0>>::foo(eval_if_c<0,boost::type_erasure::detail::maybe_const_this_param<const boost::type_erasure::_self &,Base>,boost::type_erasure::as_param<Base,const boost::type_erasure::_self &>>::type)' [found using argument-dependent lookup] with [ R=std::type_index, Base=boost::type_erasure::any_base<boost::type_erasure::any<HasGetField<std::type_index (const boost::type_erasure::_self &)>,const boost::type_erasure::_self &>> ] Source.cpp(14): note: or 'std::type_index foo(int)' Source.cpp(20): note: while trying to match the argument list '(Type)' ========================================================= Moreover, I wonder whether the declaration is a must? Thank you!

AMDG On 08/31/2015 04:53 AM, Yuan Yao wrote:
I try to use type erasure on the free function foo. However, VS 2015 failed to compile the following code, which is OK with GCC and CLang.
<snip> Source.cpp(7): note: could be 'std::type_index boost::type_erasure::injectHasGetField<R (const boost::type_erasure::_self &),Base,boost::type_erasure::index_list<0>>::foo(eval_if_c<0,boost::type_erasure::detail::maybe_const_this_param<const boost::type_erasure::_self &,Base>,boost::type_erasure::as_param<Base,const boost::type_erasure::_self &>>::type)' [found using argument-dependent lookup]
This kind of looks like a variadic template bug. The condition of the eval_if_c is supposed to evaluate to true. The whole point of this eval_if_c business is to prevent the ambiguity that you're seeing. In Christ, Steven Watanabe

在 2015/9/2 1:08, Steven Watanabe wrote:
AMDG
I try to use type erasure on the free function foo. However, VS 2015 failed to compile the following code, which is OK with GCC and CLang.
<snip> Source.cpp(7): note: could be 'std::type_index boost::type_erasure::injectHasGetField<R (const boost::type_erasure::_self &),Base,boost::type_erasure::index_list<0>>::foo(eval_if_c<0,boost::type_erasure::detail::maybe_const_this_param<const boost::type_erasure::_self &,Base>,boost::type_erasure::as_param<Base,const boost::type_erasure::_self &>>::type)' [found using argument-dependent lookup] This kind of looks like a variadic template bug. The condition of
On 08/31/2015 04:53 AM, Yuan Yao wrote: the eval_if_c is supposed to evaluate to true. The whole point of this eval_if_c business is to prevent the ambiguity that you're seeing.
In Christ, Steven Watanabe
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users You are correct. The code compiles by defining BOOST_NO_CXX11_VARIADIC_TEMPLATES. Thank you!
participants (2)
-
Steven Watanabe
-
Yuan Yao