Universal OpenGL object RAII wrapper class
Ensuring you have distinct types
You said this in the comments:

I thought that use of templates instead of a common base class would better emphasize that these objects shouldn't be mixed together (now they are completely distinct types).

Two classes that derive from the same base class are also two distinct types. Furthermore, you can make the constructor of the base class protected, so you cannot instantiate a bare base class, and you can use protected or private inheritance to ensure you cannot get a pointer to the base class from a derived class. For example:
class base {
protected:
    base() = default;
};

class derived: base {
    ...
};

derived foo;      // OK
base bar;         // Error: constructor is protected
base *baz = &amp;foo; // Error: base is inaccessible

The problem with template specialization
Your construction using template specialization has a flaw. The problem is that all member functions you might ever want to use in specializations need to be present in the default template. This is why you have:
template &lt;GLenum T&gt;
class gl_object
{
    ...
    inline gl_object( );
    inline explicit gl_object( GLenum target );
    ...
};

The second constructor that takes the target parameter is only used for gl_object&lt;GL_TEXTURE&gt;, and in fact you must have a target for the texture in order to call glCreateTextures(). The problem is now that I can do the following:
gl_object&lt;GL_BUFFER&gt; buffer(GL_TEXTURE_2D);
gl_object&lt;GL_TEXTURE&gt; texture;

The above statements will compile without errors (but perhaps with a warning), because you promised both constructors would exist. Only the linker will give an error, because there is no implementation of those constructors. But in a large project it might be hard to track down this issue.
You won't have this problem with derived classes, since you have full control over which public member functions (including constructors) each derived class has.
Alternatives without templates
There are two ways to implement this without templates. Either you say that, for example, a gl_texture &quot;is a&quot; gl_object, and use class inheritance, or you say that a gl_texture &quot;has a&quot; gl_name (the OpenGL term for the GLuint identifier given to objects), and use composition. In the first case, you'd structure your code as:
class gl_object {
protected:
    GLuint m_id;

    gl_object() = default;

    // delete copy constructors
    // add move semantics
    // access the ID
};

class gl_buffer: gl_object {
public:
    gl_buffer() {
        glCreateBuffers(1, &amp;m_id);
    }
    ...

    // Enable the default constructor and assignment operator:
    gl_buffer(gl_buffer &amp;&amp;other) = default;
    gl_buffer &amp;operator=(gl_buffer &amp;&amp;other) = default;
};

In the second case, you would write:
class gl_name {
private:
    GLuint m_id;

public:
    // delete copy constructors
    // add move semantics
    // access the ID

    GLuint &amp;get() {
        return m_id;
    }
};

class gl_buffer {
private:
    gl_name m_id;

public:
    gl_buffer() {
        glCreateBuffers(1, &amp;m_id.get());
    }
    ...

    // Enable the default constructor and assignment operator:
    gl_buffer(gl_buffer &amp;&amp;other) = default;
    gl_buffer &amp;operator=(gl_buffer &amp;&amp;other) = default;
};

In the second case, since you deleted the copy constructors for gl_name, classes that use that as a member variable will also no longer be default copy constructable.
The main drawback of either two cases is that you need to implement the move constructors and move assignment operators in each derived class. In this case the default move constructor and move assignment operator would have worked just fine, but they have been implicitly deleted. To re-enable them, just explicitly add the default move constructor and move assignemnt operator.