Clang 错误 "implicit instantiation of undefined template std::tuple_size<auto>"
Clang error "implicit instantiation of undefined template std::tuple_size<auto>"
Clang 的行为“undefined template smthg”是否有(干净的)解决方法?
代码示例:
- https://godbolt.org/z/GGs7ndKE4(copy/paste见下文)
额外的见解:
- 这个问题不能用GCC或MSVC/CL重现,
因此只影响 clang 和 clang-cl
- Clang-cl 添加以下错误信息:
error : cannot mangle this 'auto' type yet
我期望的是,根据上面提供的示例,分别获得两种类型 - evaluatable - std::tuple_size_v
:
class std::tuple<
struct std::integral_constant<bool,0>,
struct std::integral_constant<bool,1>,
struct std::integral_constant<bool,0>
>
class std::tuple<bool,bool,bool>
我漏掉了一点吗?
代码示例:
#include <tuple>
#include <array>
#include <type_traits>
template <template <typename> class trait, typename... Ts>
struct trait_result {
template <template <typename...> class T>
using as_t = T<typename trait<Ts>::type...>;
template <template <typename...> class T>
constexpr static auto as_v = T{trait<Ts>::value...};
using as_tuple_t = as_t<std::tuple>;
constexpr static auto as_tuple_v = std::tuple{trait<Ts>::value...};
};
namespace test
{
template <typename T>
using is_int = std::is_same<int, T>;
using results = trait_result<is_int, char, int, bool>;
using results_as_tuple = results::as_t<std::tuple>; // ok
using results_as_tuple_value_type = std::decay_t<decltype(results::as_v<std::tuple>)>; // ko
static_assert(std::tuple_size_v<results_as_tuple> == std::tuple_size_v<results_as_tuple_value_type>);
}
template <template <typename...> class T>
constexpr static auto as_v = T{trait<Ts>::value...};
这尝试使用T
的演绎指南来生成类型。
如果你写
auto as_v = results::as_v<std::tuple>;
编译器崩溃,甚至在您完成其余工作之前。
假设你愿意没有推导指南:
template <template <typename...> class T>
constexpr static T<decltype(trait<Ts>::value)...> as_v = {trait<Ts>::value...};
编译其余代码。
现在,
template <template <typename...> class T>
constexpr static auto as_v = T<decltype(trait<Ts>::value)...>{trait<Ts>::value...};
键入时也不会编译
auto as_v = results::as_v<std::tuple>;
所以问题可能不是演绎指南,而是constexpr static auto
这里。
这在class之外:
template<template<class...>class T, template<class>class trait, class...Ts>
constexpr auto foo = T{trait<Ts>::value...};
加上 class:
template <template <typename...> class T>
constexpr static decltype(foo<T, trait, Ts...>) as_v = foo<T, trait, Ts...>;
为您提供演绎指南并且没有内部编译器错误。
感谢 @Yakk - Adam Nevraumont,作为结论,这是我修复它的方法:
using as_array_t = std::array<std::tuple_element_t<0, decltype(std::tuple{trait<Ts>::value...})>, sizeof...(Ts)>;
constexpr static inline auto as_array_v = as_array_t{trait<Ts>::value...};
这避免了代码库中的另一个#if __clang__ /* workaround on clang ICE ... */
[编辑] 出于完整性目的:
- 即使上面的代码修复了 Clang 的编译,它也没有用于 Clang-CL。下面的代码仍然编译失败,同样的错误信息。
template <typename T>
using is_int = std::is_same<int, T>;
using results = trait_result<is_int, char, int, bool>;
using results_as_tuple = results::as_t<std::tuple>;
using results_as_tuple_value_type = std::decay_t<decltype(results::as_v<std::tuple>)>; // error here
Clang 的行为“undefined template smthg”是否有(干净的)解决方法?
代码示例:
- https://godbolt.org/z/GGs7ndKE4(copy/paste见下文)
额外的见解:
- 这个问题不能用GCC或MSVC/CL重现,
因此只影响 clang 和 clang-cl - Clang-cl 添加以下错误信息:
error : cannot mangle this 'auto' type yet
我期望的是,根据上面提供的示例,分别获得两种类型 - evaluatable - std::tuple_size_v
:
class std::tuple<
struct std::integral_constant<bool,0>,
struct std::integral_constant<bool,1>,
struct std::integral_constant<bool,0>
>
class std::tuple<bool,bool,bool>
我漏掉了一点吗?
代码示例:
#include <tuple>
#include <array>
#include <type_traits>
template <template <typename> class trait, typename... Ts>
struct trait_result {
template <template <typename...> class T>
using as_t = T<typename trait<Ts>::type...>;
template <template <typename...> class T>
constexpr static auto as_v = T{trait<Ts>::value...};
using as_tuple_t = as_t<std::tuple>;
constexpr static auto as_tuple_v = std::tuple{trait<Ts>::value...};
};
namespace test
{
template <typename T>
using is_int = std::is_same<int, T>;
using results = trait_result<is_int, char, int, bool>;
using results_as_tuple = results::as_t<std::tuple>; // ok
using results_as_tuple_value_type = std::decay_t<decltype(results::as_v<std::tuple>)>; // ko
static_assert(std::tuple_size_v<results_as_tuple> == std::tuple_size_v<results_as_tuple_value_type>);
}
template <template <typename...> class T>
constexpr static auto as_v = T{trait<Ts>::value...};
这尝试使用T
的演绎指南来生成类型。
如果你写
auto as_v = results::as_v<std::tuple>;
编译器崩溃,甚至在您完成其余工作之前。
假设你愿意没有推导指南:
template <template <typename...> class T>
constexpr static T<decltype(trait<Ts>::value)...> as_v = {trait<Ts>::value...};
编译其余代码。
现在,
template <template <typename...> class T>
constexpr static auto as_v = T<decltype(trait<Ts>::value)...>{trait<Ts>::value...};
键入时也不会编译
auto as_v = results::as_v<std::tuple>;
所以问题可能不是演绎指南,而是constexpr static auto
这里。
这在class之外:
template<template<class...>class T, template<class>class trait, class...Ts>
constexpr auto foo = T{trait<Ts>::value...};
加上 class:
template <template <typename...> class T>
constexpr static decltype(foo<T, trait, Ts...>) as_v = foo<T, trait, Ts...>;
为您提供演绎指南并且没有内部编译器错误。
感谢 @Yakk - Adam Nevraumont,作为结论,这是我修复它的方法:
using as_array_t = std::array<std::tuple_element_t<0, decltype(std::tuple{trait<Ts>::value...})>, sizeof...(Ts)>;
constexpr static inline auto as_array_v = as_array_t{trait<Ts>::value...};
这避免了代码库中的另一个#if __clang__ /* workaround on clang ICE ... */
[编辑] 出于完整性目的:
- 即使上面的代码修复了 Clang 的编译,它也没有用于 Clang-CL。下面的代码仍然编译失败,同样的错误信息。
template <typename T>
using is_int = std::is_same<int, T>;
using results = trait_result<is_int, char, int, bool>;
using results_as_tuple = results::as_t<std::tuple>;
using results_as_tuple_value_type = std::decay_t<decltype(results::as_v<std::tuple>)>; // error here