gpt4 book ai didi

c++ - 为何模板参数不参与类的定义/重新定义

转载 作者:行者123 更新时间:2023-12-03 07:11:52 25 4
gpt4 key购买 nike

为什么以下代码被禁止:

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>
{

};
我不在乎“法律上写的”方面。我只想从编译器的 Angular 来看歧义在哪里。以此类推,模板功能就可以了。
编辑:感谢来自n的评论。 '代词'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;
}
问题仍然是一样的。

最佳答案

模板功能的特化和模板类型的特化非常不同。
函数参与重载解析。重载解析是C++标准中极为复杂且会引起错误的部分。之所以“像魔术一样工作”是因为完成了很多工作才能使其工作,并且当它与模板代码进行交互时,其行为仍然令大多数人惊讶。
模板功能没有部分专门化,只有完全专门化;而特化只会改变所使用的 body ,而不会改变所选择的 body 。拥有两种不同的方式来更改交互使用的实现方式将是疯狂的。
另一方面,模板类型使用不同的方式进行选择。在这里,使用部分和完全特化,而不是重载。
特化是一种子类型化。主模板确定传递的参数是什么,而特化则不是。特化仅与主要模板的参数匹配。
您的更改将引入一组不同的主要专业 Realm 。选择您要专门研究的模板的规则必须进行更改,并且变得异常复杂,而为程序员确定要专门研究的模板也将变得更加困难。

template<class T>
struct A;
template<int x>
struct A;

template<class T, class U>
struct A< T::template apply<U> > {};
快速,我刚刚专门研究哪个模板 A<int>A<class>?现在,我现在,但是有多少人会对此感到惊讶?很多。
...
第二个问题与更早检查有关。
template <any>
struct A;
现在,当有人执行 A<T::template apply<U>>时,您将无法检查自己是否搞砸了types-vs-values,直到过程更晚。
还有什么
template<any x>
struct A: B<x> {};
现在,我们必须在 A<x>是一个类型,一个值和一个模板的假设下解析 x的正文。如果其中只有1个或2个或0个对给定的语句有效,是否会出错?
怎么样
template<any x>
struct A {
int y = x<3-x::green>;
};
如果 x是类型,则 x::green有意义,但是现在 x<?>仅在 x是模板的情况下才有意义。您是否进行了3次通过,每个假设一次?
模板解析已经很慢,昂贵且复杂。使其变得更加复杂是一件非常非常难的事。

关于c++ - 为何模板参数不参与类的定义/重新定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64897108/

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