【发布时间】:2020-11-18 16:22:48
【问题描述】:
为什么禁止以下代码:
template <std::size_t N>
struct A
{
};
template <class T>
struct A// error: different template parameter => redeclaration
{
};
知道我们可以冗长地表达相同的想法:
template <class T>
concept C_TypePack = T::is_type_pack_concept;
template <class... Types>
struct TypePack {static constexpr bool is_type_pack_concept = true;};
template <class T>
concept C_NonTypePack = T::is_non_type_pack_concept;
template <auto... NonTypes>
struct NonTypePack {static constexpr bool is_non_type_pack_concept = true;};
template <class T>
concept C_TemplatePack = T::is_template_pack_concept;
template <C_TypePack TTypePack, C_NonTypePack TNonTypePack>
struct TemplatePack {static constexpr bool is_template_pack_concept = true;};
template <C_TemplatePack TP>
struct A;
template <std::size_t N>
struct A<TemplatePack<TypePack<>, NonTypePack<N>>>
{
};
template <class T>
struct A<TemplatePack<TypePack<T>, NonTypePack<>>>
{
};
我的问题是:为什么不允许这种代码:
template <any>
struct A;
template <std::size_t N>
struct A<N>
{
};
template <class T>
struct A<T>
{
};
我不关心“它是写在法律上”的方面。我只想从编译器的角度看看歧义在哪里。以此类推,模板函数就好了。
编辑:感谢 n 的评论。 'pronouns' m.,这是使用 std::array 作为非类型的解决方法(元组也可以):
#include <array>
// type spe
template <auto Val>
struct A;
template <auto Size>
requires (std::is_same_v<decltype(Size), std::size_t>)
struct A<Size>
{
};
template <auto SizePack>
requires (std::is_same_v<typename decltype(SizePack)::value_type, std::size_t>)
struct A<SizePack>
{
};
// var spe
struct Foo
{
template <auto Val>
static consteval auto initBar()
{
if constexpr ( std::is_same_v<decltype(Val), std::size_t> )
return 5.;
else if constexpr ( requires{std::is_same_v<typename decltype(Val)::value_type, std::size_t>;} )
return -5;
else
return -1;
}
template <auto Val>
static constexpr auto bar = initBar<Val>();
};
int main()
{
A<std::size_t(42)> a0;
A<std::array<std::size_t, 1>{42}> a1;
A<std::array<std::size_t, 2>{42, 43}> a2;
Foo::bar<std::size_t(42)>;
Foo::bar<std::array<std::size_t, 1>{42}>;
Foo::bar<std::array<std::size_t, 2>{42, 43}>;
return 0;
}
问题还是一样。
【问题讨论】:
-
我的 2c:通用类型/非类型参数对于专业化很有用,但从根本上说,模板参数是代码中某些内容的占位符。您可以在哪里同时替换有效代码中的类型值和非类型值(不包括 sizeof 和 typeid)?
-
@parktomatomi:感谢 cmets。我正在设计一个多维数组,并且我有几个开始函数以 size_t(子维度 iter)或一组 size_t(自定义 iter)作为模板。可以将它们称为 begin 并考虑相同的功能,但返回的迭代器是类型别名,不能以不同的定义称为 Iterator。
-
“以此类推,模板函数就好了。”:函数模板,以及一般的函数,重载。类声明不会重载。
-
指定什么并不重要。为什么你需要一个类型呢?您的类型包含哪些值无法提供的内容?值可以是
std::tuple或std::array类型。
标签: c++ templates language-lawyer