5

While looking at C++14 the meta-function alias proposals (TransformationTraits Redux, v2,N3655), I noticed that, not only type to type transformations (such as add_const), type to value meta-functions (such as is_void ) are also type aliased. (Which are not present in N3797).

Is there any advantage of aliasing type to value meta-functions? I think, it is possible to use them without those aliases, such as enable_if_t<is_void<T>::value,T> or enable_if_t<is_void<T>{}(),T> when the conversion operation is present. (I guess is_void<T>::type::value is same as is_void<T>::value)

If the type to value meta-functions need to be aliases, wont it be better to alias them as variable template ( I do not have C++14 compiler and never used variable template. So the syntax may be wrong)? e.g. alias is_void as

template <class T>
constexpr bool is_void_t = is_void<T>::value;

Instead of

template <class T>
using is_void_t = typename is_void<T>::type;

Then one can write enable_if_t<is_void_t<T>,T> without boost style enable_if,and composing expression will be easier (e.g. enable_if_t<(is_void_t<T> || is_integral_t<T>),T>

TemplateRex
  • 69,038
  • 19
  • 164
  • 304
abir
  • 1,797
  • 14
  • 26
  • "I do not have C++14 compiler" - http://coliru.stacked-crooked.com/ – chris Nov 30 '13 at 06:51
  • @chris Do gcc 4.8 has variable template support? It looks gcc svn trunk has some support for it. clang also seems to have support for it in their trunk. Do you know any online compiler having latest c++14 snapshot to test? – abir Nov 30 '13 at 07:02
  • Coliru uses the SVN version of Clang. – chris Nov 30 '13 at 07:04
  • I just tested it, but it seems Clang 3.4 (trunk 184460) from Coliru does not have support for variable template. – abir Nov 30 '13 at 07:24
  • That's odd, especially considering other features marked SVN (like return type deduction) do work. – chris Nov 30 '13 at 07:29
  • @chris 184460 is "rather old", the current SVN trunk is 195971 AFAIK. – dyp Nov 30 '13 at 11:34

1 Answers1

4

“Is there any advantage of aliasing type to value meta-functions?”

Quoting from the linked N3655, before the specifications of is_void_t and siblings (page 4):

4   Supplementary proposed wording

The following wording is provided in response to LWG’s request that aliases for ::type members be consistently provided for all the type traits, not only for those classified as TransformationTraits. Accordingly, this section provides the specifications needed in order to complete the set.

That explains why “type to value meta-functions (such as is_void ) are also type aliased” in the proposal: for consistency.

Moreover, it would be wrong to use the name “is_void_t” to alias is_void<T>::value. The “_t” suffix always denotes a type. For the value, maybe one could use a “_v” suffix. So we would then have both:

template <class T>
using is_void_t = typename is_void<T>::type;

template <class T>
constexpr bool is_void_v = is_void<T>::value;

That should compile in C++14, and then you could write things like enable_if_t<(is_void_v<T> || is_integral_v<T>),T>. But I feel that the value alias is “less needed” than the type one: it doesn't save as much typing, and, as you said, you can use the short is_void<T>{}() with the same effect (and for C++11, is_void<T>{} is often enough, thanks to its operator bool()).

gx_
  • 4,690
  • 24
  • 31
  • *"and for C++11, `is_void{}` is often enough, thanks to its `operator bool()`"* I'd even say it's *always enough*, as those traits (*Unary* and *BinaryTypeTraits*, [meta.rqmts]) derive from `std::integral_constant`, which provides this conversion operator. – dyp Nov 30 '13 at 11:45
  • @DyP Strictly speaking, `is_void{}()` is a `bool`, but `is_void{}` is only _implicitly convertible_ to a `bool`, which might (rarely) be an “important” difference, e.g. with overload resolution or any situation where you care about the exact types. By the way, maybe that's why they added `operator()()` for C++14? (edit: found [this](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3545.pdf)) – gx_ Nov 30 '13 at 11:50
  • @gx_ While looking through C++ Draft (N3797) I had not found any reference to is_void_t etc, but only to the transform traits. Does that mean, the other aliases are not accepted? is_void_v is OK, but i had no idea _t denotes type transformation! – abir Nov 30 '13 at 11:54
  • @abir According to the Editor's Report [N3692](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3692.html): _“Section 4 of the proposal was not applied, as per the LWG motion.”_ And from [here](http://comments.gmane.org/gmane.comp.lang.c%2B%2B.isocpp.proposals/3841): _“The project editor had severe concerns in regard to this extended addition requiring about 4 additional pages in the standard with questionable value, therefore it was withdrawn at this point of time. This doesn't mean that it could not be added in the future.”_ It seems that it still hasn't been added, indeed. – gx_ Nov 30 '13 at 11:59
  • @gx_ You're right; the two reasons listed in n3545 are *to create function objects* and *to allow usage in context w/o implicit conversion, and w/o using a `static_cast`*. Though frankly I don't understand what they mean with *"The standard library’s `enable_if` and `conditional` type traits exemplify contexts that do not engender such implicit conversion."* -- AFAIK, `std::enable_if` is well-formed. – dyp Nov 30 '13 at 12:09
  • The `some_trait_v` notation has actually been proposed by Stephan T. Lavavej in [N3854](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3854.htm) and [N3932](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3932.htm) – TemplateRex Jun 08 '14 at 09:27