1

I came template code that uses * after a template type:

  ...
  template <typename _Up, typename _Ep, typename = void>
  struct _Ptr
  {
      using type = _Up*; 
  };
  ...

another usage I saw

   ...
   template <typename T, typename \
   std::enable_if<std::is_integral<T>::value,T>::type* = nullptr>
   ...

Where is this construct described?

Konrad Eisele
  • 3,088
  • 20
  • 35
  • Note that `_Up`, `_Ep` and `_Ptr` are reserved identifiers, so unless you came across that in an implementation of the standard library, the usage of the identifiers would have undefined behaviour. – eerorika Jan 16 '19 at 21:00
  • Looks like you are diving into the Standard Library implementation. Before you use this code as a Shining Example to be imitated, note that only the Standard Library implementation [is allowed to use underscores in particular ways](https://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier). – user4581301 Jan 16 '19 at 21:02
  • @eerorika: Didnt know that. I'm just browsing the unique_pointer code in /usr/include/c++/*. – Konrad Eisele Jan 16 '19 at 21:05
  • @KonradEisele well, that would explain why they use identifiers that are reserved for that very purpose. Just remember not to imitate their usage of underscores. – eerorika Jan 16 '19 at 21:06
  • 1
    @KonradEisele I would sincerely discourage you from learning C++ by looking at STL implementation. – SergeyA Jan 16 '19 at 21:07
  • @SergeyA : There is a reason though: I got irritated of the noise that is generated when using a std::unique_ptr with a std::map, which I asked here https://stackoverflow.com/questions/54223750/is-there-a-transparent-way-of-using-unique-ptr-in-std-containers . So I tried to figure out weather I can derive from std::unique_ptr that would allow me to skip the wrap/unwrap. – Konrad Eisele Jan 16 '19 at 21:25

1 Answers1

6

Means the same thing that it would mean for any type - it is a pointer to a type defined inside std::enable_if specialized for true condition, which is by default void - yielding all familiar void*.

On a completely different (and possibly ill-advised) note this is not the first time I see a question from you which touches on rather complicated topic (SFINAE is one), which demonstrates that some basic fundamentals are not there yet. I sincerely recommend reading a good C++ book - you can find curated list here: The Definitive C++ Book Guide and List

SergeyA
  • 61,605
  • 5
  • 78
  • 137
  • 1
    Also, as an aside, the standard is currently undecided on whether that is well-formed, because `void*` is not a pointer to class type. – AndyG Jan 16 '19 at 20:58
  • @AndyG that is something I am not familiar with! Do you have some further reading advice? – SergeyA Jan 16 '19 at 20:59
  • Thanks for the list to the list of books. Yes, I' still learning... "Effective Modern C++" I have actually. – Konrad Eisele Jan 16 '19 at 21:01
  • @AndyG, thanks for the link. Wasn't aware of this. But looks like this is how it is done anywhere despite this fact :D – SergeyA Jan 16 '19 at 21:06
  • 1
    @SergeyA: Indeed it does. I used this pattern for a long time before discovering this fact. It's safe to use `typename std::enable_if::type = 0` – AndyG Jan 16 '19 at 21:08
  • 1
    @AndyG I've also switched and use `typename std::enable_if::type = true`/`std::enable_if_t = true` – NathanOliver Jan 16 '19 at 21:18
  • @NathanOliver We spoke about it a couple of days back, and I immediately remembered this conversation. However, you didn't tell me why, just said it feels more descriptive to you :) – SergeyA Jan 16 '19 at 21:21