【发布时间】:2020-11-23 23:13:41
【问题描述】:
我编写了一些代码,在最新版本的 GCC 和 Clang 上编译良好,但在 MSVC 上编译失败:
模板参数“TL”的模板参数无效,应为类模板
谁能解释一下这是一个错误还是我误解了什么?
如果没有 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
【问题讨论】:
-
大概这只是一个处理注入类名的模糊性质的错误,它可以用作类型或模板。也许尝试使用
/permissive的其他值? -
为什么 list_impl 还是需要 TL?
-
@n。 '代词' m。是的,这个例子并不完整,只是显示了一个错误。完整的实现包含很多方法如
push_back/push_front/.. 并使用TL。这里的主要思想是空列表没有back和front成员,但应该重用其他逻辑。看看更详细的版本(带有push_back):pastebin.com/snRC0EPi