0

I'm writing a pointer class and have naturally defined the dereference operator as a member function. However, if this type is now void, I need to delete that function because you can't dereference a void pointer. But writing out that specialization itself is a syntax error:

// in ptr.h
template<typename T>
class ptr {
    public:
        T& operator * () const;
};


//in ptr.cpp
template<>
void& ptr<void>::operator * () const = delete;

So how can I implement this? To fix the syntax error, I have to make a syntax error?

I've tried looking in the source code for the std::unique_ptr class but I really can't make sense of that code tbh

Adriaan Jacobs
  • 309
  • 2
  • 9
  • if `T == void` and you try to dereference that pointer, your code won't compile without any other line of code (Ex `ptr p;*p;` does not compile) – Alberto Sinigaglia Jul 30 '20 at 22:28
  • @Berto99 Yes I know, that's why I want to delete it! Right now when I compile it generates code that contains 'void&', so im trying to make it not do that – Adriaan Jacobs Jul 30 '20 at 22:47
  • I'm pretty sure that it's not possible, since there is no `void&` concept in C++, be aware that this might work until you don't call the operator* – Alberto Sinigaglia Jul 30 '20 at 22:53

1 Answers1

3

You can't separate a template's declarations and implementations between header and cpp files like you are attempting to do:

Why can templates only be implemented in the header file?

In any case, you can't specialize just one method of a template class. You have to specialize the entire template, eg:

template<typename T>
class ptr {
    public:
        T& operator * () const;
};

template<>
class ptr<void> {
    public:
        // simply omit operator* altogether, since void& is illegal...
        //void& operator * () const = delete;
};

Live Demo

Otherwise, you can use SFINAE to omit the operator when T=void, eg:

#include <type_traits>

template<typename T>
class ptr {
    public:
        template<typename U = T>
        typename
            std::enable_if<!std::is_same<U, void>::value, U&>::type
        operator * () const;
};

Live Demo

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • Your first solution is how I ended up implementing it. However, it resulted in a bunch of duplicate code between the general case and the specialization, so I'll be looking into SFINAE more in the future. Thanks a bunch! – Adriaan Jacobs Aug 02 '20 at 00:42