Templated Function Pointer Arrays in Visual Studio(Visual Studio 中的模板化函数指针数组)
问题描述
Guillaume Racicot 对 这个问题关于如何专门化模板变量.但我在 visual-studio-2017 创建函数指针的模板数组.例如这段代码:
Guillaume Racicot gave an excellent answer to this question on how I could specialize template variables. But I'm having trouble in visual-studio-2017 with creating a templated array of function pointers. This code for example:
struct vec
{
double x;
double y;
double z;
};
namespace details
{
template <typename T>
constexpr double X(const T& param) { return param.x; }
template <typename T>
constexpr double Y(const T& param) { return param.y; }
template <typename T>
constexpr double Z(const T& param) { return param.z; }
}
template <typename T, typename = void>
constexpr double (*my_temp[])(const vec&) = { &details::X<T>, &details::Y<T> };
template <typename T>
constexpr double (*my_temp<T, enable_if_t<is_floating_point_v<decltype(details::X(T()))>>>[])(const vec&) = { &details::X<T>, &details::Y<T>, &details::Z<T> };
int main() {
vec foo = { 1.0, 2.0, 3.0 };
for(const auto i : my_temp<decltype(foo)>) {
cout << (*i)(foo) << endl;
}
}
在 gcc 输出中:
1
2
3
1
2
3
但是在 visual-studio-2017 仅输出:
1
2
我可以做些什么来解决这个问题吗?
Is there something I can do to work around this?
推荐答案
欢迎来到编译器错误的世界!您的语法完全有效,但只有 GCC 可以编译它.
Welcome to the world of compiler bugs! Your syntax is completely valid, yet only GCC can compile it.
到目前为止,我测试了多个 clang、gcc 和 msvc 版本.
So far, I tested with multiple clang, gcc and msvc versions.
您使用函数指针原始数组的变体,只有 GCC 可以正确解析它.Clang 8.0.0 会崩溃,MSCV 不会编译.
Your variation with the function pointer raw array, only GCC parses it correctly. Clang 8.0.0 will crash, and MSCV will not compile it.
我尝试了另外两种变体:使用模板别名和 std::array
I tried two other variations: with a template alias and std::array
函数指针别名模板:
template<typename T>
using fptr = auto(*)(T const&) -> double;
template <typename T, typename = void>
constexpr fptr<T> my_temp[] = {
&details::X<T>, &details::Y<T>
};
template <typename T>
constexpr fptr<T> my_temp<T, enable_if_t<is_floating_point_v<decltype(details::X(T()))>>>[] = {
&details::X<T>, &details::Y<T>, &details::Z<T>
};
std::array
+ CTAD:
std::array
+ CTAD:
template <typename T, typename = void>
constexpr std::array my_temp = {
&details::X<T>, &details::Y<T>
};
template <typename T>
constexpr std::array my_temp<T, enable_if_t<is_floating_point<decltype(details::X(T()))>::value>> = {
&details::X<T>, &details::Y<T>, &details::Z<T>
};
要删除 CTAD,只需使用 std::array<auto(*)(const vec&) ->双倍,3>
.
To remove CTAD, simply use std::array<auto(*)(const vec&) -> double, 3>
.
结果如下:
+------------+-------+-------+-------+
| Compiling? | GCC | Clang | MSVC |
+------------+-------+-------+-------+
| raw array | Yes | ICE | No |
+------------+-------+-------+-------+
| fptr alias | Yes | ICE | Yes |
+------------+-------+-------+-------+
| std::array | Yes | Yes | Yes |
+------------+-------+-------+-------+
请注意,在即将发布的 clang 9 中,它将与 GCC 相提并论.所有版本至少需要 MSVC 2017.通过解决方法,我确信它也可以与 msvc 2015 一起使用.
Note that on the upcoming clang 9, it will be on par with GCC. All versions needs at least MSVC 2017. With workaround I'm sure it's possible to make it work with msvc 2015 too.
最后,只要它在您现在需要的平台上运行,就可以了.std::array
的编译时间成本很小,但到目前为止,原始数组的可移植性令人惊讶.
In the end, as long as it work on the platform you need right now, that would be okay. std::array
have a small compile time cost, but the raw array is surprisingly less portable as of right now.
这篇关于Visual Studio 中的模板化函数指针数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:Visual Studio 中的模板化函数指针数组
基础教程推荐
- Windows Media Foundation 录制音频 2021-01-01
- 为 C/C++ 中的项目的 makefile 生成依赖项 2022-01-01
- 在 C++ 中循环遍历所有 Lua 全局变量 2021-01-01
- 为什么语句不能出现在命名空间范围内? 2021-01-01
- 从 std::cin 读取密码 2021-01-01
- 使用从字符串中提取的参数调用函数 2022-01-01
- 如何使图像调整大小以在 Qt 中缩放? 2021-01-01
- 管理共享内存应该分配多少内存?(助推) 2022-12-07
- 如何在不破坏 vtbl 的情况下做相当于 memset(this, ...) 的操作? 2022-01-01
- 如何“在 Finder 中显示"或“在资源管理器中显 2021-01-01