假设我有以下示例类型:
template < class T = void > struct Test { };
template < > struct Test<void> { };
此类型推导指南:
template<class T> Test() -> Test<T>;
下面的编译就可以了:
Test f;
在GCC上。
但是,在Clang上。推导指南必须为:
template<class T = void> Test() -> Test<T>;
所以我的问题是:哪个是正确的?
默认模板类型应同时存在于推导类型和基本类型中,还是仅存在于基本类型中,并假定它将由编译器选择。
GCC和Clang的主干版本均使用-O3 -std=c++17
在godbolt.org上进行了测试
答案 0 :(得分:4)
首先,您实际上不需要这种类型的推导指南-假设类模板参数已经默认。如果您提供推论指南,则应为:
Test() -> Test<void>;
将其设为演绎指南模板没有任何意义。
也就是说,我认为这不是一个错误……来自任何一个编译器。正如您的示例所做的那样,编写包含非推导模板参数的推导指南没有什么错误:
template<class T> Test() -> Test<T>;
但是,尽管标准允许该构造,但实际上也没有任何意义。演绎指南的重点是...演绎指南。如果您提供不可推论的扣除指南,那有什么意义?此处的Clang错误似乎对我很有帮助-它在提醒您您编写的代码明显错误的事实。
如果我们要上学,那就是lang虫。但是实际上,我比ccc更喜欢clang的结果。