Con*_*nos 7 c++ templates language-lawyer c++14
在下面的示例中,Abstract是一个类模板,其第一个参数是一个类型,第二个参数是另一个模板,它带有一个bool以及任意数量的args.
template<bool,typename>
struct Default;
template< typename T = void,
template<bool,typename ...> class = Default>
struct Abstract;
template<typename T>
struct Abstract<T>
{};
template<typename T, template<bool> class C>
struct Abstract<T,C> : Abstract<T>
{};
int main()
{}
Run Code Online (Sandbox Code Playgroud)
Clang和C++的输出如下:
Clang: http ://rextester.com/BJSW46677
错误:类模板部分特化没有专门化任何模板参数;
G ++ http://rextester.com/MDN65674
好
所以,我决定对clang友好,并在Abstract声明中添加了第三个参数.
template< typename T = void,
template<bool,typename ...> class = Default,
typename = void >
struct Abstract;
Run Code Online (Sandbox Code Playgroud)
现在,Clang和G ++都很好.我想Clang抱怨的原因是因为专业化并没有真正专门化.但事实并非如此.它专门针对参数的数量.
接下来,我为模板模板参数添加了另一个专门化.示例如下所示:
template<bool,typename>
struct Default;
template< typename T = void,
template<bool,typename ...> class = Default,
typename = void >
struct Abstract;
template<typename T>
struct Abstract<T>
{};
template<typename T, template<bool> class C>
struct Abstract<T,C> : Abstract<T>
{};
template<typename T, template<bool,typename> class G>
struct Abstract<T,G> : Abstract<T>
{};
int main()
{}
Run Code Online (Sandbox Code Playgroud)
Clang和C++的输出如下:
Clang: http ://rextester.com/LJIOC38789
错误:重新定义
Abstract<type-parameter-0-0, C, void>注释:以前的定义是struct Abstract<T,C> : Abstract<T>
G ++: http ://rextester.com/TSDRZ44717
好的 - (也不需要声明中的第三个参数)
我不认为 Clang就在这里,因为第三个专门化对模板模板参数有效,并且variadic模板参数允许我专门用于任意数量的参数.但是,我不确定.
问题:哪个编译器是错误的?为什么?从规范中获得一个引用并且对该主题更加清晰是非常好的.
正如评论中指出的,问题的第一部分\xe2\x80\x94,即是否允许专门研究作为主模板\xe2\x80\x94 中的可变参数模板的模板模板参数本质上是与另一个问题相同。如果您阅读了我对该问题的回答,它包含了部分专业化的部分排序规则如何工作的摘要。特别是在您的情况下,问题是从 C++17 开始,template<bool,typename ...> class参数可以接受template<bool> class参数,反之亦然;这意味着在 C++17 及更高版本中,部分排序规则得出的结论是您编写的部分特化并不比主模板更特化,这使得程序格式错误。
(FWIW,Godbolt 上可用的最新版本的 Clang trunk 接受专业化,我希望 CWG2398 最终能够以一种使该代码格式良好的方式得到解决。)
\n至于你的问题的第二部分,关于一对部分专业化:
\ntemplate<typename T, template<bool> class C>\nstruct Abstract<T,C> : Abstract<T>\n{};\n\ntemplate<typename T, template<bool,typename> class G>\nstruct Abstract<T,G> : Abstract<T>\n{};\nRun Code Online (Sandbox Code Playgroud)\nClang 的某些版本声称第二个版本是第一个版本的“重新声明”,这纯粹是无稽之谈;这可能是这些版本中的一个错误。这是固定在行李箱中的。
\n| 归档时间: |
|
| 查看次数: |
300 次 |
| 最近记录: |