首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为嵌套模板类声明operator==

为嵌套模板类声明operator==
EN

Stack Overflow用户
提问于 2018-10-18 08:06:25
回答 2查看 302关注 0票数 9

在另一个模板类中有以下嵌套模板类:

代码语言:javascript
复制
template<typename T>
struct A
{
    template<typename V>
    struct B {};
};

嵌套类型operator==的非会员B的签名是什么?以下天真的尝试不起作用:

代码语言:javascript
复制
template<typename T, typename V>
bool operator==(A<T>::B<V> left, A<T>::B<V> right);

Clang、GCC和MSVC给出了各种不同的错误和/或提示什么是错误的,比如缺少template关键字,但我试图解决它的任何尝试都没有奏效。

请注意,这显然是有效的:

代码语言:javascript
复制
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解析源代码,它要求我提供的声明,我实际上已经实现了,如刚才所示.

现场演示

EN

回答 2

Stack Overflow用户

发布于 2019-06-28 17:15:16

错误并不太远,因为您确实需要template关键字,但还需要type type来表示依赖类型。一个有用的例子是这样的形式:

代码语言:javascript
复制
template <typename T, typename V>
bool operator==(typename A<T>::template B<V> left,
                typename A<T>::template B<V> right) {...}

不过,我建议:

代码语言:javascript
复制
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

票数 0
EN

Stack Overflow用户

发布于 2018-10-18 09:51:45

您可以有内联朋友声明和大纲定义。

代码语言:javascript
复制
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的朋友。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52869573

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档