C++ 部分特化不适用于不同大小的特征矩阵
C++ Partial Specialization Not Working for Differing Size Eigen Matrices
在过去的几个小时里,我一直在撞墙,试图弄清楚为什么一些部分模板专业化失败了,我真的可以使用一些帮助。
基本上,我正在处理一些依赖于在编译时了解矩阵大小的代码,但我正在尝试使用模板来做。使用类型组合似乎存在某种我真的不明白的问题。为了说明,请考虑以下(稍微毫无意义的(代码:
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(,这就是为什么我认为这个问题特定于特征矩阵。
编辑:实际上,这似乎与我在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,所以我需要一个解决方法。有人有什么想法吗?
为了使其完整,@chtz在上面的评论中建议的解决方案完全适用于MSVC 2015和2017。通过问题中特定不同大小问题的示例,这非常有效:
template <typename T1, typename T2> struct typen { typedef bool bar; };
template <typename T, int R, int M, int C, int O1, int O2, int Rc1, int Rc2, int Cc1, int Cc2>
struct typen<Matrix<T, R, M, O1, Rc1, Cc1>, Matrix<T, M, C, O2, Rc2, Cc2>> { typedef Matrix<T, R, C> bar; };
...
/* true :-) */ Test<typen<Matrix<float, 2, 3>, Matrix<float, 3, 4>>::bar>::foo();
相关文章:
- FLTK 2.0构建和演示,适用于VS2019的2011年左右的代码库
- C++17 - 使用自定义分配器的节点提取/重新插入 - 适用于 clang++/libc++,但不适用于 libstd
- "string.h"在构建适用于iOS的qt应用程序中找不到消息
- 适用于 WebView2 旧版本的示例应用程序
- 在 NVIDIA GEFORCE GTX 1050 上下载适用于 Windows 10 的 openCL 1.2
- __attribute__(优化(0))) 是否适用于"recursively"?
- 为什么 std::erase(std::erase_if) 不是适用于<algorithm>任何容器的模板?
- 使用一个参数的模板函数时出错(适用于 2)
- 使用 适用于 Android 和 iOS 的 tf-lite C++ API
- 为什么这适用于 G++ 而不是 CLANG?
- 适用于 macOS 的 Xcode 应用程序。这就是我设置从USB麦克风输入获取音频的方式。一年前工作,现在没有了。为什么
- 基于 SFINAE 的特征,用于确定是否支持运算符 +
- 适用于 Linux 的 c++ 上的代理脚本
- 为什么我的 SFINAE 表达式不再适用于 GCC 8.2?
- 使输出流式处理运算符适用于 boost::variant<std::vector<int>、int、double 的正确方法是什么>
- 有没有适用于Windows.lib文件的GNU二进制文件描述符(BFD)
- 模板函数仅适用于VS
- 如何在cmake中包含适用于g++或viceversa的库
- 哪些适用于 Windows 的 C++11 编译器支持新的类型特征,如"is_nothrow_move_constructible"?
- 使用enable_if选择特征-适用于clang,但不适用于gcc