Opened 8 years ago
Last modified 5 years ago
#9953 new Feature Requests
lazy_enable_if is not sfinae friendly
Reported by: | Owned by: | Peter Dimov | |
---|---|---|---|
Milestone: | To Be Determined | Component: | core |
Version: | Boost 1.55.0 | Severity: | Problem |
Keywords: | Cc: |
Description
The following code fails to compile, even though boost::result_of itself is sfinae friendly.
template < typename T > typename boost::lazy_enable_if_c< boost::is_class<T>::value, boost::result_of<T(int)> >::type test(int){} template < typename > void test(...) {} struct A{}; // boost::result_of<A(int)> is a valid type that doesn't have a member called "type" int main(int argc, const char * argv[]) { test<A>(0); // test<A>(int) meant to be a substitution failure return 0; }
I'm not sure if this is a bug/flaw, or a lack of feature, or maybe this kind of use is deliberately disallowed for some reason, but it could be very useful if lazy_enable_if_c<bool B, typename T>
etc support uses when typename T::type
itself may cause a substitution failure.
Proposing to change implementation of lazy_enable_if_c
and lazy_disable_if_c
to:
template <bool B, class T> struct lazy_enable_if_c : T {}; // inherits from T template <class T> struct lazy_enable_if_c<false, T> {}; template <bool B, class T = void> struct disable_if_c : T {}; // inherits from T template <class T> struct disable_if_c<true, T> {};
Change History (2)
comment:1 by , 8 years ago
comment:2 by , 5 years ago
Component: | utility → core |
---|---|
Owner: | changed from | to
This might be useful. Deriving from T
won't work if it is final
, but in C++11 we could reformulate lazy_enable_if_c
like this:
template< bool Cond, typename T > using lazy_enable_if_c = typename enable_if_c< Cond, T >::type::type;
I should mention what error i get when compiling the test code. On clang++-3.4 with -std=c++11, I got: