【发布时间】:2021-06-20 06:02:43
【问题描述】:
Q1:在命名空间范围内是否允许用户定义的推导指南?
在此处的示例中,GCC 和 Clang 不会产生相同的行为:
#include <tuple>
template <typename T>
struct some_type;
template <template <typename...> typename T, typename ... Ts>
struct some_type<T<Ts...>>
{
template <typename U>
class nested
{
U member;
public:
nested(U &&){}
};
// non-namespace scope user-deduction-guide : OK with Clang, fix the deduction issue
template <typename U>
nested(U&&) -> nested<U>;
};
void func()
{
using pack_type = std::tuple<int, char>;
some_type<pack_type>::nested{
[](auto &&){}
};
}
简而言之,我们有一个模板参数类型,嵌套类型本身就是模板参数,模板参数之间没有任何关系。
template <typename T>
struct some_type;
template <template <typename...> typename T, typename ... Ts>
struct some_type<T<Ts...>>
{
template <typename U>
class nested // <- nested type, where `U` as no relationship with `T<Ts...>`
{
U member;
public:
nested(U &&);
};
};
标准指定:http://eel.is/c++draft/temp.deduct.guide#3
[...] 演绎指南应在与相应类模板相同的范围内声明,并且对于成员类模板,具有相同的访问权限。 [...]
Q2 : 如果no到Q1,在namespace-type和nested-type没有关系的情况下,为嵌套类型创建自定义推导指南的语法是什么模板参数?
我希望语法接近:
template <template <typename...> typename T, typename ... Ts>
template <typename U>
some_type<T<Ts...>>::nested<U>::nested(U&&) -> nested<U>;
但是,nested<U> 是错误,因为它需要一个推导类型 ... 来推导它。
此外,这被解释为具有尾随返回类型 void 的函数。
template <template <typename...> typename T, typename ... Ts>
template <typename U>
typename some_type<T<Ts...>>::template nested<U>::nested(U&&) -> nested<U>;
感谢您的宝贵时间。
【问题讨论】:
-
第一季度的代码。使用 GCC 提供 ICE,您应该将其报告为错误。
-
视觉与clang Demo一致。
-
@cigien:我会的,一如既往。
-
@Jarod42 :是的,谢谢,我预料到了,因为 Msvc 和 Clang 越来越倾向于产生相同的行为 :)
-
您的意思是 Q1 被“允许在非命名空间范围内”吗?无需点击godbolt即可查看问题中的第一个示例代码会很有帮助。