--- a/src/mlpack/core/cv/meta_info_extractor.hpp
+++ b/src/mlpack/core/cv/meta_info_extractor.hpp
@@ -38,50 +38,142 @@
          bool NumClasses>
 struct TrainForm;
 
-template<typename PT, typename WT, typename... SignatureParams>
-struct TrainFormBase
-{
-  using PredictionsType = PT;
-  using WeightsType = WT;
-
-  /* A minimum number of parameters that should be inferred */
-  static const size_t MinNumberOfAdditionalArgs = 1;
-
-  template<typename Class, typename RT, typename... Ts>
-  using Type = RT(Class::*)(SignatureParams..., Ts...);
-};
-
-template<typename MT, typename PT>
-struct TrainForm<MT, PT, void, false, false> : public TrainFormBase<PT, void,
-    const MT&, const PT&> {};
-
-template<typename MT, typename PT>
-struct TrainForm<MT, PT, void, true, false> : public TrainFormBase<PT, void,
-    const MT&, const data::DatasetInfo&, const PT&> {};
-
-template<typename MT, typename PT, typename WT>
-struct TrainForm<MT, PT, WT, false, false> : public TrainFormBase<PT, WT,
-    const MT&, const PT&, const WT&> {};
-
-template<typename MT, typename PT, typename WT>
-struct TrainForm<MT, PT, WT, true, false> : public TrainFormBase<PT, WT,
-    const MT&, const data::DatasetInfo&, const PT&, const WT&> {};
-
-template<typename MT, typename PT>
-struct TrainForm<MT, PT, void, false, true> : public TrainFormBase<PT, void,
-    const MT&, const PT&, const size_t> {};
-
-template<typename MT, typename PT>
-struct TrainForm<MT, PT, void, true, true> : public TrainFormBase<PT, void,
-    const MT&, const data::DatasetInfo&, const PT&, const size_t> {};
-
-template<typename MT, typename PT, typename WT>
-struct TrainForm<MT, PT, WT, false, true> : public TrainFormBase<PT, WT,
-    const MT&, const PT&, const size_t, const WT&> {};
-
-template<typename MT, typename PT, typename WT>
-struct TrainForm<MT, PT, WT, true, true> : public TrainFormBase<PT, WT,
-    const MT&, const data::DatasetInfo&, const PT&, const size_t, const WT&> {};
+#if _MSC_VER <= 1916 // Visual Studio 2017 version 15.9 or older.
+  // Due to an internal MSVC compiler bug (MSVC ) we can't use two parameter
+  // packs. So we have to write multiple TrainFormBase forms.
+  template<typename PT, typename WT, typename T1, typename T2>
+  struct TrainFormBase4
+  {
+    using PredictionsType = PT;
+    using WeightsType = WT;
+
+    /* A minimum number of parameters that should be inferred */
+    static const size_t MinNumberOfAdditionalArgs = 1;
+
+    template<typename Class, typename RT, typename... Ts>
+    using Type = RT(Class::*)(T1, T2, Ts...);
+  };
+
+  template<typename PT, typename WT, typename T1, typename T2, typename T3>
+  struct TrainFormBase5
+  {
+    using PredictionsType = PT;
+    using WeightsType = WT;
+
+    /* A minimum number of parameters that should be inferred */
+    static const size_t MinNumberOfAdditionalArgs = 1;
+
+    template<typename Class, typename RT, typename... Ts>
+    using Type = RT(Class::*)(T1, T2, T3, Ts...);
+  };
+
+  template<typename PT, typename WT, typename T1, typename T2, typename T3,
+      typename T4>
+  struct TrainFormBase6
+  {
+    using PredictionsType = PT;
+    using WeightsType = WT;
+
+    /* A minimum number of parameters that should be inferred */
+    static const size_t MinNumberOfAdditionalArgs = 1;
+
+    template<typename Class, typename RT, typename... Ts>
+    using Type = RT(Class::*)(T1, T2, T3, T4, Ts...);
+  };
+
+  template<typename PT, typename WT, typename T1, typename T2, typename T3,
+      typename T4, typename T5>
+  struct TrainFormBase7
+  {
+    using PredictionsType = PT;
+    using WeightsType = WT;
+
+    /* A minimum number of parameters that should be inferred */
+    static const size_t MinNumberOfAdditionalArgs = 1;
+
+    template<typename Class, typename RT, typename... Ts>
+    using Type = RT(Class::*)(T1, T2, T3, T4, T5, Ts...);
+  };
+
+  template<typename MT, typename PT>
+  struct TrainForm<MT, PT, void, false, false> : public TrainFormBase4<PT, void,
+      const MT&, const PT&> {};
+
+  template<typename MT, typename PT>
+  struct TrainForm<MT, PT, void, true, false> : public TrainFormBase5<PT, void,
+      const MT&, const data::DatasetInfo&, const PT&> {};
+
+  template<typename MT, typename PT, typename WT>
+  struct TrainForm<MT, PT, WT, false, false> : public TrainFormBase5<PT, WT,
+      const MT&, const PT&, const WT&> {};
+
+  template<typename MT, typename PT, typename WT>
+  struct TrainForm<MT, PT, WT, true, false> : public TrainFormBase6<PT, WT,
+      const MT&, const data::DatasetInfo&, const PT&, const WT&> {};
+
+  template<typename MT, typename PT>
+  struct TrainForm<MT, PT, void, false, true> : public TrainFormBase5<PT, void,
+      const MT&, const PT&, const size_t> {};
+
+  template<typename MT, typename PT>
+  struct TrainForm<MT, PT, void, true, true> : public TrainFormBase6<PT, void,
+      const MT&, const data::DatasetInfo&, const PT&, const size_t> {};
+
+  template<typename MT, typename PT, typename WT>
+  struct TrainForm<MT, PT, WT, false, true> : public TrainFormBase6<PT, WT,
+      const MT&, const PT&, const size_t, const WT&> {};
+
+  template<typename MT, typename PT, typename WT>
+  struct TrainForm<MT, PT, WT, true, true> : public TrainFormBase7<PT, WT,
+      const MT&, const data::DatasetInfo&, const PT&,
+      const size_t, const WT&> {};
+#else
+  template<typename PT, typename WT, typename... SignatureParams>
+  struct TrainFormBase
+  {
+    using PredictionsType = PT;
+    using WeightsType = WT;
+
+    /* A minimum number of parameters that should be inferred */
+    static const size_t MinNumberOfAdditionalArgs = 1;
+
+    template<typename Class, typename RT, typename... Ts>
+    using Type = RT(Class::*)(SignatureParams..., Ts...);
+  };
+
+  template<typename MT, typename PT>
+  struct TrainForm<MT, PT, void, false, false> : public TrainFormBase<PT, void,
+      const MT&, const PT&> {};
+
+  template<typename MT, typename PT>
+  struct TrainForm<MT, PT, void, true, false> : public TrainFormBase<PT, void,
+      const MT&, const data::DatasetInfo&, const PT&> {};
+
+  template<typename MT, typename PT, typename WT>
+  struct TrainForm<MT, PT, WT, false, false> : public TrainFormBase<PT, WT,
+      const MT&, const PT&, const WT&> {};
+
+  template<typename MT, typename PT, typename WT>
+  struct TrainForm<MT, PT, WT, true, false> : public TrainFormBase<PT, WT,
+      const MT&, const data::DatasetInfo&, const PT&, const WT&> {};
+
+  template<typename MT, typename PT>
+  struct TrainForm<MT, PT, void, false, true> : public TrainFormBase<PT, void,
+      const MT&, const PT&, const size_t> {};
+
+  template<typename MT, typename PT>
+  struct TrainForm<MT, PT, void, true, true> : public TrainFormBase<PT, void,
+      const MT&, const data::DatasetInfo&, const PT&, const size_t> {};
+
+  template<typename MT, typename PT, typename WT>
+  struct TrainForm<MT, PT, WT, false, true> : public TrainFormBase<PT, WT,
+      const MT&, const PT&, const size_t, const WT&> {};
+
+  template<typename MT, typename PT, typename WT>
+  struct TrainForm<MT, PT, WT, true, true> : public TrainFormBase<PT, WT,
+      const MT&, const data::DatasetInfo&, const PT&,
+      const size_t, const WT&> {};
+#endif
 
 /* A struct for indication that a right method form can't be found */
 struct NotFoundMethodForm
