diff --git a/include/ADIOS.h b/include/ADIOS.h
index f289c278aab493907ae5071133761423c5abb6e3..56a469c3ee7a7e62abc6ec10f5b61821e55fd4b0 100644
--- a/include/ADIOS.h
+++ b/include/ADIOS.h
@@ -21,6 +21,7 @@
 #include <vector>
 /// \endcond
 
+#include "ADIOSMacros.h"
 #include "ADIOS_MPI.h"
 
 #include "ADIOSTypes.h"
@@ -354,20 +355,18 @@ protected: // no const to allow default empty and copy constructors
     std::map<unsigned int, Variable<T>> &GetVarMap();
 };
 
-template <class T>
-VariableCompound &ADIOS::DefineVariableCompound(const std::string &name,
-                                                const Dims dimensions,
-                                                const Dims globalDimensions,
-                                                const Dims globalOffsets)
-{
-    CheckVariableInput(name, dimensions);
-    const unsigned int size = m_Compound.size();
-    m_Compound.emplace(size, VariableCompound(name, sizeof(T), dimensions,
-                                              globalDimensions, globalOffsets,
-                                              m_DebugMode));
-    m_Variables.emplace(name, std::make_pair(GetType<T>(), size));
-    return m_Compound.at(size);
-}
+// Explicit declaration of the template methods
+#define declare_template_instantiation(T)                                      \
+    extern template Variable<T> &ADIOS::DefineVariable<T>(                     \
+        const std::string &name, const Dims, const Dims, const Dims);          \
+    extern template Variable<T> &ADIOS::GetVariable<T>(const std::string &);   \
+    extern template unsigned int ADIOS::GetVariableIndex<T>(                   \
+        const std::string &name);                                              \
+    template <>                                                                \
+    std::map<unsigned int, Variable<T>> &ADIOS::GetVarMap<T>();
+ADIOS_FOREACH_TYPE_1ARG(declare_template_instantiation)
+extern template unsigned int ADIOS::GetVariableIndex<void>(const std::string &);
+#undef declare_template_instantiation
 
 } // end namespace adios
 
diff --git a/include/ADIOS.tcc b/include/ADIOS.tcc
new file mode 100644
index 0000000000000000000000000000000000000000..de230eef77a0449d2bfb4d65cb8253117c878995
--- /dev/null
+++ b/include/ADIOS.tcc
@@ -0,0 +1,34 @@
+/*
+ * Distributed under the OSI-approved Apache License, Version 2.0.  See
+ * accompanying file Copyright.txt for details.
+ *
+ * ADIOS.tcc
+ *   This contains the template implementations for the ADIOS class
+ */
+
+#ifndef ADIOS_TCC_
+#define ADIOS_TCC_
+
+#include "ADIOS.h"
+
+namespace adios
+{
+
+template <class T>
+VariableCompound &ADIOS::DefineVariableCompound(const std::string &name,
+                                                const Dims dimensions,
+                                                const Dims globalDimensions,
+                                                const Dims globalOffsets)
+{
+    CheckVariableInput(name, dimensions);
+    const unsigned int size = m_Compound.size();
+    m_Compound.emplace(size, VariableCompound(name, sizeof(T), dimensions,
+                                              globalDimensions, globalOffsets,
+                                              m_DebugMode));
+    m_Variables.emplace(name, std::make_pair(GetType<T>(), size));
+    return m_Compound.at(size);
+}
+
+} // end namespace adios
+
+#endif /* ADIOS_TCC_ */
diff --git a/source/ADIOSMacros.h b/include/ADIOSMacros.h
similarity index 100%
rename from source/ADIOSMacros.h
rename to include/ADIOSMacros.h
diff --git a/source/ADIOS.tcc b/source/ADIOS_inst.cpp
similarity index 83%
rename from source/ADIOS.tcc
rename to source/ADIOS_inst.cpp
index ebfc628c6058a4e0761e58b13469f815bfacc0f7..c494bc3e286c886d983af23e1ea09bb90bff8721 100644
--- a/source/ADIOS.tcc
+++ b/source/ADIOS_inst.cpp
@@ -3,22 +3,10 @@
  * accompanying file Copyright.txt for details.
  *
  * ADIOS.tcc
- *   This contains the template specialization implementations for the ADIOS
- *   class
+ *   This contains the template specializatios for the ADIOS class
  */
 
-#ifndef ADIOS_TCC_
-#define ADIOS_TCC_
-
-#include <complex>
-#include <map>
-#include <memory> //std::shared_ptr
-#include <ostream>
-#include <set>
-#include <string>
-#include <vector>
-
-#include "ADIOS.h"
+#include "ADIOS.tcc"
 #include "ADIOSMacros.h"
 
 namespace adios
@@ -125,7 +113,7 @@ std::map<unsigned int, Variable<std::complex<long double>>> &ADIOS::GetVarMap()
 }
 
 // -----------------------------------------------------------------------------
-// template specializations of DefineVariable:
+// explicit template instantiations of DefineVariable:
 // -----------------------------------------------------------------------------
 
 template <typename T>
@@ -142,14 +130,14 @@ ADIOS::DefineVariable(const std::string &name, const Dims dimensions,
     return varMap.at(size);
 }
 
-#define instantiate_specialization(T)                                          \
+#define define_template_instantiation(T)                                       \
     template Variable<T> &ADIOS::DefineVariable<T>(                            \
         const std::string &, const Dims, const Dims, const Dims);
-ADIOS_FOREACH_TYPE_1ARG(instantiate_specialization)
-#undef instantiate_specialization
+ADIOS_FOREACH_TYPE_1ARG(define_template_instantiation)
+#undef define_template_instatiation
 
 // -----------------------------------------------------------------------------
-// template specializations of DefineVariable:
+// template specializations of GetVariable:
 // -----------------------------------------------------------------------------
 
 template <class T>
@@ -163,18 +151,17 @@ unsigned int ADIOS::GetVariableIndex(const std::string &name)
     return itVariable->second.second;
 }
 
-// Get template specialization
 template <typename T>
 Variable<T> &ADIOS::GetVariable(const std::string &name)
 {
     return GetVarMap<T>().at(GetVariableIndex<T>(name));
 }
 
-#define instantiate_specialization(T)                                          \
+#define define_template_instatiation(T)                                        \
+    template unsigned int ADIOS::GetVariableIndex<T>(const std::string &);     \
     template Variable<T> &ADIOS::GetVariable<T>(const std::string &);
-ADIOS_FOREACH_TYPE_1ARG(instantiate_specialization)
-#undef instantiate_specialization
+ADIOS_FOREACH_TYPE_1ARG(define_template_instatiation)
+template unsigned int ADIOS::GetVariableIndex<void>(const std::string &);
+#undef define_template_instatiation
 
 } // end namespace adios
-
-#endif /* ADIOS_TCC_ */
diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt
index aa8debffd5447aaf78a559058ce56fc41e36c2c4..f4a1bf83f52dd731e07b42090d0aa1311276a0da 100644
--- a/source/CMakeLists.txt
+++ b/source/CMakeLists.txt
@@ -4,7 +4,7 @@
 #------------------------------------------------------------------------------#
 
 add_library(adios2
-  ADIOS.cpp
+  ADIOS.cpp ADIOS.tcc ADIOS_inst.cpp
   #ADIOS_C.cpp
 
   capsule/heap/STLVector.cpp