gpt4 book ai didi

c++ - 为什么 MSVC 无法编译此 CRTP 代码?

转载 作者:行者123 更新时间:2023-12-03 10:04:38 24 4
gpt4 key购买 nike

我编写了一些在最新版本的 GCC 和 Clang 上编译良好的代码,但在 MSVC 上失败:

invalid template argument for template parameter 'TL', expected a class template


谁能解释一下这是一个错误还是我误解了什么?
没有 types_list 的部分特化它在 MSVC 上也可以正常工作。
#include <cstdint>
#include <type_traits>

namespace detail
{
template <std::size_t Index, typename ...Ts>
struct get
{
static_assert(Index < sizeof...(Ts), "types_list::get index out of bounds");

private:
template <std::size_t CurrentIndex, typename ...Us>
struct helper
{
using type = void;
};

template <std::size_t CurrentIndex, typename U, typename ...Us>
struct helper<CurrentIndex, U, Us...>
{
using type = std::conditional_t<CurrentIndex == Index, U, typename helper<CurrentIndex + 1, Us...>::type>;
};

public:
using type = typename helper<0, Ts...>::type;
};

template <template <typename...> typename TL, typename ...Ts>
struct list_impl
{
inline static constexpr std::size_t size = sizeof...(Ts);

template <std::size_t Index>
using get = typename detail::get<Index, Ts...>::type;
};
}

template <typename ...Ts>
struct types_list : public detail::list_impl<types_list, Ts...>
{
};

template <typename T, typename ...Ts>
struct types_list<T, Ts...> : public detail::list_impl<types_list, T, Ts...>
{
private:
using impl = detail::list_impl<types_list, T, Ts...>;

public:
using front = typename impl:: template get<0>;
using back = typename impl:: template get<impl::size - 1>;
};

using t = types_list<int, double>::front;
using t2 = types_list<int, double>::back;
using t3 = types_list<int, char, double>::get<1>;

int main()
{
t x = 10;
t2 y = 1.4;
t3 z = 'a';
}
编辑:更详细的示例 https://pastebin.com/snRC0EPi

最佳答案

这似乎确实是错误。要引用当前实例化,您通常可以省略当前类型的模板参数。这就是 MSVC 似乎在这里所做的。它会导致错误,因为模板需要模板模板参数。
但是为什么要使用模板模板参数呢?对于 CRTP,您使用“绑定(bind)模板类型”。

更新
如果您需要使用新参数实例化模板,可以使用帮助类型轻松完成:

namespace helper{
template<
typename VariadicType
>
class GetTemplateOfVariadicType{
};

template<
template <typename...> typename Template,
typename... Ts
>
class GetTemplateOfVariadicType<Template<Ts...>>
{
public:
template<typename... T>
using type = Template<T...>;
};
}
用法:
using OtherTL = typename ::helper::GetTemplateOfVariadicType<TL>::template type<int, bool, char>;
见这里: godbolt

关于c++ - 为什么 MSVC 无法编译此 CRTP 代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64977982/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com