【发布时间】:2017-08-15 02:01:42
【问题描述】:
在过去的几个小时里,我一直在努力想弄清楚为什么某些部分模板专业化失败了,我真的可以使用一些帮助。
基本上,我正在编写一些代码,这些代码依赖于在编译时了解矩阵的大小,但我正在尝试使用模板进行通用。使用我真的不明白的类型组合似乎存在某种问题。作为说明,请考虑以下(有点无意义的)代码:
template <typename T> struct type1 { typedef bool bar; };
template <typename T, int R, int C> struct type1<Matrix<T, R, C>> { typedef Matrix<T, R, C> bar; };
template <typename T1, typename T2> struct type2 { typedef bool bar; };
template <typename T, int R, int M, int C> struct type2<Matrix<T, R, M>, Matrix<T, M, C>> { typedef Matrix<float, 2, 2> bar; };
template <typename T1, typename T2> struct type3 { typedef bool bar; };
template <typename T, int R, int M, int C> struct type3<Matrix<T, R, M>, Matrix<T, M, C>> { typedef Matrix<T, R, C> bar; };
template <typename T> struct Test {
static bool foo() {
return false;
}
};
template <typename T, int R, int C> struct Test<Matrix<T, R, C>> {
static bool foo() {
return true;
}
};
我对模板组合的理解是,这些模板应该能够以如下方式组合,其中每一行都应该返回 true。但是请注意,最后两个返回 false。
/* true <- */ Test<Matrix<float, 2, 2>>::foo();
/* true <- */ Test<Matrix<float, 6, 3>>::foo();
/* true <- */ Test<type1<Matrix<float, 2, 7>>::bar>::foo();
/* And so on for any other size . . . */
/* true <- */ Test<type2<Matrix<float, 3, 3>, Matrix<float, 3, 3>>::bar>::foo();
/* true <- */ Test<type3<Matrix<float, 2, 2>, Matrix<float, 2, 2>>::bar>::foo();
/* And so on for any other pair of square sizes . . . */
/* false <- */ Test<type2<Matrix<float, 2, 3>, Matrix<float, 3, 2>>::bar>::foo();
/* false <- */ Test<type3<Matrix<float, 2, 4>, Matrix<float, 4, 1>>::bar>::foo();
/* And so on for any other pair of non-square sizes . . . */
特别奇怪的是,当我用任意的 template <typename T, int R, int C> struct Thing 替换 Eigen::Matrix 时,一切都按预期工作(即所有测试都返回 true),这就是为什么我认为这个问题是 Eigen 矩阵特有的。
编辑:实际上,这似乎与我在 MSVC 上构建的事实有关(在 2015 年和 2017 年同样失败)。当我在 g++ 或 clang 上编译它时,它工作正常。更多的证据表明 Visual c++ 是一团糟(并不是真的需要它)。
此外,它似乎实际上与两个参数具有不同大小的情况有关。例如:
template <typename T1, typename T2> struct typetest { typedef bool bar; };
template <typename T, int R1, int C1, int R2, int C2> struct typetest<Matrix<T, R1, C1>, Matrix<T, R2, C2>> { typedef Matrix<float, 2, 2> bar; };
当第一个和第二个矩阵类型具有相同的大小时成功,但当它们不同时失败。例如:
/* true <- */ Test<typetest<Matrix<float, 2, 3>, Matrix<float, 2, 3>>::bar>::foo();
/* true <- */ Test<typetest<Matrix<float, 6, 1>, Matrix<float, 6, 1>>::bar>::foo();
/* false <- */ Test<typetest<Matrix<float, 2, 2>, Matrix<float, 2, 3>>::bar>::foo();
/* false <- */ Test<typetest<Matrix<float, 5, 3>, Matrix<float, 2, 4>>::bar>::foo();
不幸的是,由于一些非常烦人的依赖关系,我暂时主要使用 MSVC,所以我需要一个解决方法。有人有什么想法吗?
【问题讨论】:
-
Eigen::Matrix 对我来说一切正常(没有错误值)。我可以给个截图。
-
顺便用的是最新的3.3.4。
-
错误信息是?
-
已经举报,见here
-
作为一种解决方法,您是否尝试过
template <typename T, int R, int C, int O, int Rc, int Cc> struct Test<Matrix<T, R, C, O, Rc, Cc>> {...,即添加Eigen::Matrix的可选/隐式模板参数? (我没有 MSVC,所以无法测试)
标签: c++ templates matrix metaprogramming eigen