I speculate that you have an ODR problem, so there is little sense in guessing why some compiler optimization behaves differently from another compiler setting.
In essence, the One Definition Rule states that the same entity should have the exact same definition throughout an application, otherwise the effects are undefined.
The fundamental problem is that the code that doesn't see the specialized version of your class template member function might still compile, is likely to link, and sometimes might even run. This is because in the absence of (a forward declaration of) the explicit specialization, the non-specialized version kicks in, likely implementing a generic functionality that works for your specialized type as well.
So if you are lucky, you get a compiler error about missing declarations/definitions, but if you are really unlucky you get "working" code that does not what you intend it to do.
The fix: always include (forward) declarations of all template specializations. It's best to put those in a single header and include that header from all clients that call your class for any possible template argument.
// my_template.hpp
#include "my_template_fwd.hpp"
#include "my_template_primary.hpp"
#include "my_template_spec_some_type.hpp"
// my_template_fwd.hpp
template<typename> class my_template; // forward declaration of the primary template
// my_template_primary.hpp
#include "my_template_fwd.hpp"
template<typename T> class my_template { /* full definition */ };
// my_template_spec_some_type.hpp
#include "my_template_fwd.hpp"
template<> class my_template<some_type> { /* full definition */ };
// some_client_module.hpp
#include "my_template.hpp" // no ODR possible, compiler will always see unique definition
Obviously, you could reorganize the naming by making subdirectories for template specializations and change the include paths accordingly.