使用嵌套模板变量解决 Visual Studio 内部编译器错误
Working Around a Visual Studio Internal Compiler Error With Nested Templated Variables
我正在尝试编写可以让我对函数的参数类型进行索引的代码:
template <typename R, typename... ARGS>
R function_return(R(*)(ARGS...));
template <typename R, typename... ARGS>
std::tuple<ARGS...> function_parameters(R(*)(ARGS...));
template <int I, typename T>
using get_type = typename std::conditional_t<(I < 0), std::tuple_element<static_cast<int>(std::tuple_size_v<T>) + I, T>, std::tuple_element<I, T>>::type;
template <int I, typename T>
using parameter_type = get_type<I, decltype(function_parameters(std::declval<T>()))>;
Live Example (ICE under VS)
Live Example (working on GCC)
但是当我尝试在 visual-studio-2017 上使用它时,我得到一个内部编译器错误:
fatal error C1001: An internal error has occurred in the compiler.
是否有另一种方法可以解决内部编译器错误?
这可能取决于 VS2017 的确切(子)版本,因为我的代码不会生成 ICE。但是,该代码仍然存在问题,因为它可能会实例化 std::tuple_element<2147483647, T>
或类似的东西。您需要确保只评估正确的分支。将 get_type
的定义替换为:
template <int I, typename T, bool negative = (I < 0)>
struct get_type_impl;
template <int I, typename T>
struct get_type_impl<I, T, true>
{
using type = typename std::tuple_element<static_cast<int>(std::tuple_size<T>::value) + I, T>::type;
};
template <int I, typename T>
struct get_type_impl<I, T, false>
{
using type = typename std::tuple_element<I, T>::type;
};
template <int I, typename T>
using get_type = typename get_type_impl<I, T>::type;
这适用于我的 VS 2017(cl 版本 19.12)
因为 it seems like visual-studio-2017 struggles with templated using statements being passed to each other. (I'm seeing the internal compiler error on 15.6.7; as 这可能已通过补丁修复。)
我已经能够通过在单个 using 语句中捕获所有功能来解决它:
template <typename R, typename... ARGS>
R function_return(R(*)(ARGS...));
template <typename R, typename... ARGS>
std::tuple<ARGS...> function_parameters(R(*)(ARGS...));
template <int I, typename T, typename X = decltype(function_parameters(std::declval<T>()))>
using parameter_type = typename std::conditional_t<(I < 0), std::tuple_element<static_cast<int>(std::tuple_size_v<X>) + I, X>, std::tuple_element<I, X>>::type;
我正在尝试编写可以让我对函数的参数类型进行索引的代码:
template <typename R, typename... ARGS>
R function_return(R(*)(ARGS...));
template <typename R, typename... ARGS>
std::tuple<ARGS...> function_parameters(R(*)(ARGS...));
template <int I, typename T>
using get_type = typename std::conditional_t<(I < 0), std::tuple_element<static_cast<int>(std::tuple_size_v<T>) + I, T>, std::tuple_element<I, T>>::type;
template <int I, typename T>
using parameter_type = get_type<I, decltype(function_parameters(std::declval<T>()))>;
Live Example (ICE under VS) Live Example (working on GCC)
但是当我尝试在 visual-studio-2017 上使用它时,我得到一个内部编译器错误:
fatal error C1001: An internal error has occurred in the compiler.
是否有另一种方法可以解决内部编译器错误?
这可能取决于 VS2017 的确切(子)版本,因为我的代码不会生成 ICE。但是,该代码仍然存在问题,因为它可能会实例化 std::tuple_element<2147483647, T>
或类似的东西。您需要确保只评估正确的分支。将 get_type
的定义替换为:
template <int I, typename T, bool negative = (I < 0)>
struct get_type_impl;
template <int I, typename T>
struct get_type_impl<I, T, true>
{
using type = typename std::tuple_element<static_cast<int>(std::tuple_size<T>::value) + I, T>::type;
};
template <int I, typename T>
struct get_type_impl<I, T, false>
{
using type = typename std::tuple_element<I, T>::type;
};
template <int I, typename T>
using get_type = typename get_type_impl<I, T>::type;
这适用于我的 VS 2017(cl 版本 19.12)
因为
我已经能够通过在单个 using 语句中捕获所有功能来解决它:
template <typename R, typename... ARGS>
R function_return(R(*)(ARGS...));
template <typename R, typename... ARGS>
std::tuple<ARGS...> function_parameters(R(*)(ARGS...));
template <int I, typename T, typename X = decltype(function_parameters(std::declval<T>()))>
using parameter_type = typename std::conditional_t<(I < 0), std::tuple_element<static_cast<int>(std::tuple_size_v<X>) + I, X>, std::tuple_element<I, X>>::type;