lmi
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [lmi] enable_if boost to std rosetta stone


From: Vadim Zeitlin
Subject: Re: [lmi] enable_if boost to std rosetta stone
Date: Mon, 23 Jan 2017 21:41:52 +0100

On Mon, 23 Jan 2017 18:24:31 +0000 Greg Chicares <address@hidden> wrote:

GC> Now I wonder about two things. First, given that the Committee added
GC> std::enable_if_t to C++14 to provide a less verbose idiom, why didn't
GC> they go all the way and do what you've done?

 I can only speculate here, but I think that enable_if_t was just a
straightforward generalization of enable_if in the same vein as many other
foo_t aliases were added for foo::type. OTOH replacing the boolean template
argument with a type argument would be a different and bespoke change that,
I guess, was deemed not worth the extra effort, especially because with
C++17 you have another generic change consisting in adding bar_v aliases
for all bar::values, so in C++17 you can write

        std::enable_if_t<std::is_same_v<X,Y>>

which is almost as short as our version and doesn't involve neither any
duplication nor any inconsistencies as having enable_if_t<> taking a type
would inevitably involve.


GC> Second, if I remove the code that you suggested and I mangled above
GC> from its namespace, bringing it into the global namespace, it no longer
GC> works. Is this some obvious mechanical error on my part,

 Yes, although I'm afraid it's based on my own error: you can't have
"typename" keyword which isn't followed by a "nested name specifier" in the
Standard lingo. I.e. if there is no "::", you can't use it. I'm too lazy to
check, but I think that it is allowed, but just useless, when used as in my
original patch, i.e. "typename namespace_name::class_name", but it's
definitely not allowed in the just "typename class_name" case.

 The solution is trivial: just remove "typename".

GC> +template<typename Y, typename X>
GC> +inline Y sfinae_cast_2
GC> +    (X const& x
GC> +    ,typename enable_iff_t<std::is_same<X,Y>>* = nullptr
          ^^^^^^^^^
 Here.

GC> +    )
GC> +{
GC> +    return x;
GC> +}
GC> +
GC> +template<typename Y, typename X>
GC> +inline Y sfinae_cast_2
GC> +    (X const&
GC> +//  ,typename enable_iff_t<!std::is_same<X,Y> >* = nullptr
GC> +//             error: template argument 1 is invalid ^
GC> +//  i.e., "::type" was elided and cannot be negated here
GC> +//  so a distinct "disable" version is needed:
GC> +    ,typename disable_iff_t<std::is_same<X,Y> >* = nullptr
          ^^^^^^^^^
 And here.

 After doing, the test compiles and passes for me, but I've only tested it
under Linux so far.

 Hope this helps,
VZ


reply via email to

[Prev in Thread] Current Thread [Next in Thread]