简体   繁体   English

Clang 错误“未定义模板 std::tuple_size 的隐式实例化<auto> ”</auto>

[英]Clang error “implicit instantiation of undefined template std::tuple_size<auto>”

Is there a (clean) work-around to Clang's behavior "undefined template smthg<auto>"? Clang 的行为“未定义的模板 smthg<auto>”是否有(干净的)解决方法?

Code example:代码示例:

Additional insight:额外的见解:

  • This issue is not reproductible with GCC nor MSVC/CL ,此问题不适用于GCCMSVC/CL
    thus only affect clang and clang-cl因此只影响clangclang-cl
  • Clang-cl add the following error message: Clang-cl 添加如下错误信息:
     error: cannot mangle this 'auto' type yet

What I'd expect is that, according the example provided above, to get respectively two types with the same - evaluatable - std::tuple_size_v :我期望的是,根据上面提供的示例,分别获得具有相同 - 可评估 - 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>

Am I missing a point?我错过了一点吗?

Code example:代码示例:

#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...};

this attempts to use the deduction guide of T to generate a type.这试图使用T的推导指南来生成一个类型。

If you write如果你写

auto as_v = results::as_v<std::tuple>;

the compiler crashes, even before the rest of your work.编译器崩溃,甚至在您工作的 rest 之前。

Assuming you are willing to do without the deduction guide:假设您愿意不使用扣除指南:

template <template <typename...> class T>
constexpr static T<decltype(trait<Ts>::value)...> as_v = {trait<Ts>::value...};

makes the rest of the code compile.使代码的 rest 编译。

Now,现在,

template <template <typename...> class T>
constexpr static auto as_v = T<decltype(trait<Ts>::value)...>{trait<Ts>::value...};

also doesn't compile when you type键入时也不会编译

auto as_v = results::as_v<std::tuple>;

so it might not be the deduction guide that is the problem, but rather constexpr static auto here.所以问题可能不是扣除指南,而是这里的constexpr static auto

This outside of the class:这在 class 之外:

template<template<class...>class T, template<class>class trait, class...Ts>
constexpr auto foo = T{trait<Ts>::value...};

together with this inside the class:连同 class 内部的这个:

template <template <typename...> class T>
constexpr static decltype(foo<T, trait, Ts...>) as_v = foo<T, trait, Ts...>;

gives you deduction guides and no internal compiler errors.为您提供演绎指南,并且没有内部编译器错误。

Thanks to @Yakk - Adam Nevraumont , and as conclusion, here is the way I fixed it:感谢@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...};

This avoid another #if __clang__ /* workaround on clang ICE... */ in the codebase这避免了代码库中#if __clang__ /* workaround on clang ICE... */

[EDIT] For completeness purpose: [编辑]出于完整性目的:

  • Even if the code above fixed compilation for Clang, it did not for Clang-CL.即使上面的代码修复了 Clang 的编译,它也没有用于 Clang-CL。 The following code still failed to compile, with the same error message.以下代码仍然无法编译,并显示相同的错误消息。
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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM