Boost C++ Libraries: Ticket #9953: lazy_enable_if is not sfinae friendly https://svn.boost.org/trac10/ticket/9953 <p> The following code fails to compile, even though boost::result_of itself is sfinae friendly. </p> <pre class="wiki">template &lt; typename T &gt; typename boost::lazy_enable_if_c&lt; boost::is_class&lt;T&gt;::value, boost::result_of&lt;T(int)&gt; &gt;::type test(int){} template &lt; typename &gt; void test(...) {} struct A{}; // boost::result_of&lt;A(int)&gt; is a valid type that doesn't have a member called "type" int main(int argc, const char * argv[]) { test&lt;A&gt;(0); // test&lt;A&gt;(int) meant to be a substitution failure return 0; } </pre><p> 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 <code>lazy_enable_if_c&lt;bool B, typename T&gt;</code> etc support uses when <code>typename T::type</code> itself may cause a substitution failure. </p> <p> Proposing to change implementation of <code>lazy_enable_if_c</code> and <code>lazy_disable_if_c</code> to: </p> <pre class="wiki">template &lt;bool B, class T&gt; struct lazy_enable_if_c : T {}; // inherits from T template &lt;class T&gt; struct lazy_enable_if_c&lt;false, T&gt; {}; template &lt;bool B, class T = void&gt; struct disable_if_c : T {}; // inherits from T template &lt;class T&gt; struct disable_if_c&lt;true, T&gt; {}; </pre> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/9953 Trac 1.4.3 anonymous Fri, 25 Apr 2014 10:57:13 GMT <link>https://svn.boost.org/trac10/ticket/9953#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/9953#comment:1</guid> <description> <p> I should mention what error i get when compiling the test code. On clang++-3.4 with -std=c++11, I got: </p> <pre class="wiki">clang++-mp-3.4 -std=c++11 -I /opt/local/include/ main.cpp In file included from main.cpp:1: In file included from /opt/local/include/boost/type_traits.hpp:65: In file included from /opt/local/include/boost/type_traits/is_nothrow_move_assignable.hpp:22: /opt/local/include/boost/utility/enable_if.hpp:40:25: error: no type named 'type' in 'boost::result_of&lt;A (int)&gt;' typedef typename T::type type; ~~~~~~~~~~~~^~~~ main.cpp:12:1: note: in instantiation of template class 'boost::lazy_enable_if_c&lt;true, boost::result_of&lt;A (int)&gt; &gt;' requested here typename boost::lazy_enable_if_c&lt; ^ main.cpp:16:1: note: while substituting explicitly-specified template arguments into function template 'test' test(int){} ^ 1 error generated. </pre> </description> <category>Ticket</category> </item> <item> <dc:creator>Andrey Semashev</dc:creator> <pubDate>Sat, 08 Jul 2017 20:37:35 GMT</pubDate> <title>owner, component changed https://svn.boost.org/trac10/ticket/9953#comment:2 https://svn.boost.org/trac10/ticket/9953#comment:2 <ul> <li><strong>owner</strong> changed from <span class="trac-author">No-Maintainer</span> to <span class="trac-author">Peter Dimov</span> </li> <li><strong>component</strong> <span class="trac-field-old">utility</span> → <span class="trac-field-new">core</span> </li> </ul> <p> This might be useful. Deriving from <code>T</code> won't work if it is <code>final</code>, but in C++11 we could reformulate <code>lazy_enable_if_c</code> like this: </p> <pre class="wiki">template&lt; bool Cond, typename T &gt; using lazy_enable_if_c = typename enable_if_c&lt; Cond, T &gt;::type::type; </pre> Ticket