[utility][enable_if]Fiddly function lookup failure on msvc11
Hi,
I found a part of my code failed to compile with boost::enable_if_c when I
was porting my code for msvc11 (Visual Studio 2012). The original code was
bit too complex but I simplified it to boil down the issue. The simplified
code is eventually like this:
#include
::type get_one(T) { return 1; }
void test() { get_one('a'); // Compile fails at this line with error C2893 } msvc11 fails to resolve the call to get_one() but I believe the code is definitely correct. With some more extra test, I found: (1)The same code compiles on msvc10 (Visual Studio 2010) and msvc9 (Visual Studio 2008). (2)If I changed the line I commented "//Argument of boost::mpl::not_" to "boost::mpl::true_", the code compiled on msvc11. template <class T> inline typename boost::enable_if_c< !boost::mpl::not_< boost::mpl::true_ // *** Argument of boost::mpl::not_ >::type::value // Refer the result of boost::mpl::not_ , int
::type get_one(T) { return 1; }
(3)If changed the line I commented "// Refer the result of boost::mpl::not_" to ">::value", the code compiled on msvc11. template <class T> inline typename boost::enable_if_c< !boost::mpl::not_< always_true<T> // Argument of boost::mpl::not_ >::value // *** Refer the result of boost::mpl::not_ , int
::type get_one(T) { return 1; }
The issue seems to be rather a compiler quirk of msvc11 than a enable_if's problem, but I posted the issue here because we need a workaround to avoid it (on msvc11) when we use enable_if. Please let me know if you have any idea about the issue. Thanks. Yamamoto
On 10/7/2013 9:41 AM, Quoth 山本賢一:
template <class T> struct always_true : boost::mpl::true_ { }; [...] The issue seems to be rather a compiler quirk of msvc11 than a enable_if's problem, but I posted the issue here because we need a workaround to avoid it (on msvc11) when we use enable_if. Please let me know if you have any idea about the issue. Thanks.
Does the behaviour change if you make always_true not a template, or if you make some member of it actually depend on the template argument?
2013/10/7 Gavin Lambert
On 10/7/2013 9:41 AM, Quoth 山本賢一:
template <class T>
struct always_true : boost::mpl::true_ { };
[...]
Does the behaviour change if you make always_true not a template, or if you make some member of it actually depend on the template argument?
The behaviour changed and the code compiled if I changed always_true not a template. struct always_true : boost::mpl::true_ { }; template <class T> inline typename boost::enable_if_c< !boost::mpl::not_< always_true >::type::value , int
::type get_one(T) { return 1; }
The behaviour didn't change and the code didn't compile if I made some member of always_true actually depend on the template argument. template <class T> struct always_true : boost::mpl::true_ { typedef typename boost::add_const<T>::type unused_type; }; The actual condition to reproduce the issue seems very complex. My best guess is that msvc11 gives up resolving template-parameter-dependent condition and marks it as failure (in the sense of SFINAE) under a specific circumstance.
On 10/7/2013 8:06 AM, 山本賢一 wrote:
2013/10/7 Gavin Lambert
On 10/7/2013 9:41 AM, Quoth 山本賢一:
template <class T>
struct always_true : boost::mpl::true_ { };
[...]
Does the behaviour change if you make always_true not a template, or if you make some member of it actually depend on the template argument?
The behaviour changed and the code compiled if I changed always_true not a template.
struct always_true : boost::mpl::true_ { };
template <class T> inline typename boost::enable_if_c< !boost::mpl::not_< always_true >::type::value , int
::type
How about trying another "boost::mpl::not_" rather than "!" in the above code. Does that make any difference ?
get_one(T) { return 1; }
The behaviour didn't change and the code didn't compile if I made some member of always_true actually depend on the template argument.
template <class T> struct always_true : boost::mpl::true_ { typedef typename boost::add_const<T>::type unused_type; };
The actual condition to reproduce the issue seems very complex. My best guess is that msvc11 gives up resolving template-parameter-dependent condition and marks it as failure (in the sense of SFINAE) under a specific circumstance.
participants (3)
-
Edward Diener
-
Gavin Lambert
-
山本賢一