在另一个模板类中有以下嵌套模板类:
template<typename T>
struct A
{
template<typename V>
struct B {};
};嵌套类型operator==的非会员B的签名是什么?以下天真的尝试不起作用:
template<typename T, typename V>
bool operator==(A<T>::B<V> left, A<T>::B<V> right);Clang、GCC和MSVC给出了各种不同的错误和/或提示什么是错误的,比如缺少template关键字,但我试图解决它的任何尝试都没有奏效。
请注意,这显然是有效的:
template<typename T>
struct A
{
template<typename V>
struct B {};
template<typename V>
friend bool operator==(B<V> left, B<V> right)
{
return true;
}
};然而,需要行外非会员声明的原因是使用qdoc记录它。qdoc正在使用clang解析源代码,它要求我提供的声明,我实际上已经实现了,如刚才所示.。
发布于 2019-06-28 17:15:16
错误并不太远,因为您确实需要template关键字,但还需要type type来表示依赖类型。一个有用的例子是这样的形式:
template <typename T, typename V>
bool operator==(typename A<T>::template B<V> left,
typename A<T>::template B<V> right) {...}不过,我建议:
template <typename T, typename V>
using operator_type = typename A<T>::template B<V>;
template <typename T, typename V>
bool operator==(operator_type<T, V> left,
operator_type<T, V> right) {...}作为减轻某些深奥语法的手段。这是一个奇怪的问题,您期望typename足够表示::B是A的依赖名称,但您仍然需要模板关键字,因为解析器在处理<和>时非常混乱。这个答案很好地解释了为什么:
在名称查找(3.4)发现一个名称是一个模板名称之后,如果这个名称后面跟着一个<,那么<总是被视为模板参数列表的开头,而不是一个后跟少于操作符的名称。现在,我们回到了与typename相同的问题上。如果我们还不知道在解析代码时名称是否是模板呢?我们需要像14.2/4所指定的那样,在模板名称之前插入模板。
t::template f<int>(); // call a function template
发布于 2018-10-18 09:51:45
您可以有内联朋友声明和大纲定义。
template<typename T>
struct A
{
template<typename V>
struct B
{
friend bool operator==(B left, B right);
};
};
template <typename T, typename V>
bool operator==(typename A<T>::template B<V> left, typename A<T>::template B<V> right)
{
return true;
}然而gcc警告说
警告:朋友声明
bool operator==(A<T>::B<V>, A<T>::B<V>)声明了一个非模板函数-Wnon模板朋友 注意:(如果这不是您想要的,请确保函数模板已经声明,并在这里的函数名之后添加<>)
为了修正这一警告,我们必须在定义operator==(B left, B right)之前转发声明B,这只能在A中,这将迫使它也成为A的朋友。
https://stackoverflow.com/questions/52869573
复制相似问题