SFINAE broken in Visual C++ Express?
Hello! Does anybody else experience a problem using enable_if templates in Visual C++ Express 2005 SP1? I get compiler errors in this code: template<class LookUpType_> typename boost::enable_if_c<is_const, result_type>::type at(LookUpType_ const& key)const { return has_key(view_, key); } template<class LookUpType_> typename boost::disable_if_c<is_const, result_type>::type at(LookUpType_ const& key) { return has_key(view_, key); } It blames that type is not a member of enable_if_c or disable_if_c? This is really strance, since this should not be considered by compiler as a possible template instantiation. is_const is an enum value containing either true or false.
I think we'd have to see the return value of has_key to solve this mystery. It has to match your, rather complex, return type, after all. mike On Tue, 2007-10-30 at 15:35 +0100, Ovanes Markarian wrote:
Hello!
Does anybody else experience a problem using enable_if templates in Visual C++ Express 2005 SP1? I get compiler errors in this code:
template<class LookUpType_> typename boost::enable_if_c<is_const, result_type>::type at(LookUpType_ const& key)const { return has_key(view_, key); }
template<class LookUpType_> typename boost::disable_if_c<is_const, result_type>::type at(LookUpType_ const& key) { return has_key(view_, key); }
It blames that type is not a member of enable_if_c or disable_if_c? This is really strance, since this should not be considered by compiler as a possible template instantiation. is_const is an enum value containing either true or false.
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
on Tue Oct 30 2007, "Ovanes Markarian" <om_boost-AT-keywallet.com> wrote:
Hello!
Does anybody else experience a problem using enable_if templates in Visual C++ Express 2005 SP1? I get compiler errors in this code:
template<class LookUpType_> typename boost::enable_if_c<is_const, result_type>::type at(LookUpType_ const& key)const { return has_key(view_, key); }
template<class LookUpType_> typename boost::disable_if_c<is_const, result_type>::type at(LookUpType_ const& key) { return has_key(view_, key); }
It blames that type is not a member of enable_if_c or disable_if_c? This is really strance, since this should not be considered by compiler as a possible template instantiation. is_const is an enum value containing either true or false.
In order for SFINAE to work, at least one argument to [dis|en]able_if has to depend on a template argument (in this case, LookUpType_ is the only one). As written, none of them do. I don't know what you're doing with is_const, but at least in the Boost world that is a template that requires a template argument in that context. For example, template<class LookUpType_> typename boost::disable_if_c<boost::is_const<LookUpType_>, result_type>::type at(LookUpType_ const& key) { return has_key(view_, key); } HTH, -- Dave Abrahams Boost Consulting http://www.boost-consulting.com
Ok! Thanks! I got it... The problem is, that I thought that SFINAE would work from the template class in the template function which does not depend on the argument. is_const is a member of the traits_class which this type is derived from... Pretty much like: template<class T> struct traits_class { // some type calcs here typedef ... result_type; enum { is_const = false }; }; template<class T> struct traits_class<const T> { // some type calcs here typedef ... result_type; enum { is_const = true }; }; template<class T> struct some_class : traits_class<T> { template<class LookUpType_> typename boost::disable_if_c<is_const, result_type>::type at(LookUpType_ const& key) { return has_key(view_, key); //has key is some external function, which receives the result_type from the view_ } }; My idea was to enable only result_type at(LookUpType_ const& key) const; if T is const OR enable non-const version. result_type at(LookUpType_ const& key); if T is not const On the other hand Compiler does this for me automatically if T is const (but if T is non-const I would like to disable the const access). Anyway in that case I thought SFINAE should work, but it did not. Do I really need a type to be a template param of the member function, even if the class is a template itself? Thanks for your help! Ovanes On 10/31/07, David Abrahams <dave@boost-consulting.com> wrote:
on Tue Oct 30 2007, "Ovanes Markarian" <om_boost-AT-keywallet.com> wrote:
Hello!
Does anybody else experience a problem using enable_if templates in Visual C++ Express 2005 SP1? I get compiler errors in this code:
template<class LookUpType_> typename boost::enable_if_c<is_const, result_type>::type at(LookUpType_ const& key)const { return has_key(view_, key); }
template<class LookUpType_> typename boost::disable_if_c<is_const, result_type>::type at(LookUpType_ const& key) { return has_key(view_, key); }
It blames that type is not a member of enable_if_c or disable_if_c? This is really strance, since this should not be considered by compiler as a possible template instantiation. is_const is an enum value containing either true or false.
In order for SFINAE to work, at least one argument to [dis|en]able_if has to depend on a template argument (in this case, LookUpType_ is the only one). As written, none of them do.
I don't know what you're doing with is_const, but at least in the Boost world that is a template that requires a template argument in that context. For example,
template<class LookUpType_> typename boost::disable_if_c<boost::is_const<LookUpType_>, result_type>::type at(LookUpType_ const& key) { return has_key(view_, key); }
HTH,
-- Dave Abrahams Boost Consulting http://www.boost-consulting.com
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
on Wed Oct 31 2007, "Ovanes Markarian" <om_boost-AT-keywallet.com> wrote:
Ok! Thanks! I got it... The problem is, that I thought that SFINAE would work from the template class in the template function which does not depend on the argument.
is_const is a member of the traits_class which this type is derived from... Pretty much like:
template<class T> struct traits_class { // some type calcs here typedef ... result_type; enum { is_const = false }; };
template<class T> struct traits_class<const T> { // some type calcs here typedef ... result_type; enum { is_const = true }; };
template<class T> struct some_class : traits_class<T> {
template<class LookUpType_> typename boost::disable_if_c<is_const, result_type>::type at(LookUpType_ const& key) { return has_key(view_, key); //has key is some external function, which receives the result_type from the view_ }
};
My idea was to enable only result_type at(LookUpType_ const& key) const; if T is const
OR enable non-const version. result_type at(LookUpType_ const& key); if T is not const
On the other hand Compiler does this for me automatically if T is const (but if T is non-const I would like to disable the const access).
Anyway in that case I thought SFINAE should work, but it did not. Do I really need a type to be a template param of the member function, even if the class is a template itself?
No, it needs to be _dependent_ on a template parameter of the member function. Here's an evil trick you can use: template <bool b, class Ignored> struct make_dependent { enum { value = b }; }; template<class T> struct some_class : traits_class<T> { template<class LookUpType_> typename boost::disable_if_c< make_dependent<some_class::is_const, LookUpType_>::value, result_type >::type at(LookUpType_ const& key) { return has_key(view_, key); //has key is some external function, which receives the result_type from the view_ } }; Enjoy, -- Dave Abrahams Boost Consulting http://www.boost-consulting.com
participants (3)
-
David Abrahams
-
Michael Linck
-
Ovanes Markarian